From 3b25e840d39e9b1335e7059a89404fa86e40a51b Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Wed, 3 Feb 2021 15:46:32 -0700 Subject: [PATCH 001/211] Widen analyzer dependency range to fix dev channel builds --- pubspec.yaml | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index d29ee9ca2..4da63ab4f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,10 +10,13 @@ environment: dependencies: collection: ^1.14.11 - analyzer: '>=0.35.0 <0.40.0' + analyzer: '>=0.40.0 <0.42.0' build: ^1.0.0 - built_redux: ^7.4.2 - built_value: '>=5.4.4 <8.0.0' + built_redux: + git: + url: https://github.com/aaronlademann-wf/built_redux.git + ref: widen-analyzer-range + built_value: '>=6.8.2 <9.0.0' dart_style: ^1.2.5 js: ^0.6.1+1 logging: ">=0.11.3+2 <1.0.0" @@ -23,7 +26,7 @@ dependencies: react: ^6.0.0 redux: ">=3.0.0 <5.0.0" source_span: ^1.4.1 - transformer_utils: ^0.2.0 + transformer_utils: ^0.2.6 w_common: ^1.13.0 w_flux: ^2.10.4 platform_detect: ^1.3.4 @@ -34,10 +37,14 @@ dev_dependencies: build_resolvers: ^1.0.5 build_runner: ^1.7.1 build_test: ^0.10.9 - build_web_compilers: ^2.5.1 - built_value_generator: '>=6.0.0 <8.0.0' + build_web_compilers: + git: + url: https://github.com/aaronlademann-wf/build.git + ref: allow-bazel-worker-nullsafety/build_modules + path: build_web_compilers + built_value_generator: '>=7.0.0 <9.0.0' dart2_constant: ^1.0.0 - dart_dev: ^3.0.0 + dart_dev: ^3.6.4 dependency_validator: ^1.4.0 glob: ^1.2.0 io: ^0.3.2+1 @@ -51,3 +58,11 @@ workiva: core_checks: version: 1 react_boilerplate: disabled + + +dependency_overrides: + build_modules: + git: + url: https://github.com/aaronlademann-wf/build.git + ref: allow-bazel-worker-nullsafety/build_modules + path: build_modules From 155d73e07ce00633c7ccd65806f3b93d79e4fd8d Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Thu, 4 Feb 2021 16:09:17 -0700 Subject: [PATCH 002/211] Move git diff check to its own step --- .github/workflows/dart_ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dart_ci.yml b/.github/workflows/dart_ci.yml index d989ea3d6..2005f1339 100644 --- a/.github/workflows/dart_ci.yml +++ b/.github/workflows/dart_ci.yml @@ -40,7 +40,7 @@ jobs: # Analyze before generated files are created to verify that component boilerplate analysis is "clean" without the need for building - name: Analyze example source (pre-build) run: | - # Analyze lib to ensure public APIs don't depend on build-to-cache files, + # Analyze lib to ensure public APIs don't depend on build-to-cache files, # which could cause analysis issues for consumers who haven't run a build yet. dartanalyzer lib cd example/boilerplate_versions @@ -53,8 +53,11 @@ jobs: name: Build generated files / precompile DDC assets run: | pub run build_runner build --delete-conflicting-outputs -o ddc_precompiled - git diff --exit-code if: always() && steps.install.outcome == 'success' + + - name: Verify that generated files are up-to-date + run: git diff --exit-code + if: always() && steps.install.build == 'success' # Analyze again after generated files are created to verify that those generated classes don't cause analysis errors - name: Analyze project source (post-build) From e8305c44dda5905aa2b9f4db53dfe9ef9e4567af Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Thu, 4 Feb 2021 16:50:17 -0700 Subject: [PATCH 003/211] Try adding comments to speed up dev build? --- .github/workflows/dart_ci.yml | 4 ++-- example/boilerplate_versions/main.dart | 2 ++ example/builder/main.dart | 2 ++ example/context/main.dart | 2 ++ example/hooks/main.dart | 2 ++ test/over_react_component_declaration_test.dart | 2 ++ test/over_react_component_test.dart | 2 ++ test/over_react_dom_test.dart | 2 ++ test/over_react_redux_test.dart | 2 ++ test/over_react_util_test.dart | 2 ++ web/component1/index.dart | 2 ++ web/component1/src/demos/button/index.dart | 2 ++ web/component1/src/demos/list-group/index.dart | 2 ++ web/component1/src/demos/progress/index.dart | 2 ++ web/component1/src/demos/tag/index.dart | 2 ++ web/component2/index.dart | 2 ++ web/component2/src/demos/list-group/index.dart | 2 ++ web/component2/src/demos/progress/index.dart | 2 ++ web/component2/src/demos/tag/index.dart | 2 ++ .../advanced/examples/flux_implementation/index.dart | 2 ++ .../advanced/examples/influx_implementation/index.dart | 2 ++ .../advanced/examples/redux_implementation/index.dart | 2 ++ .../simple/examples/flux_implementation/index.dart | 2 ++ .../simple/examples/influx_implementation/index.dart | 2 ++ .../simple/examples/redux_implementation/index.dart | 2 ++ web/over_react_redux/examples/dev_tools/index.dart | 2 ++ web/over_react_redux/examples/multiple_stores/index.dart | 2 ++ web/over_react_redux/examples/simple/index.dart | 2 ++ 28 files changed, 56 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dart_ci.yml b/.github/workflows/dart_ci.yml index 2005f1339..5ff3fe89d 100644 --- a/.github/workflows/dart_ci.yml +++ b/.github/workflows/dart_ci.yml @@ -54,10 +54,10 @@ jobs: run: | pub run build_runner build --delete-conflicting-outputs -o ddc_precompiled if: always() && steps.install.outcome == 'success' - + - name: Verify that generated files are up-to-date run: git diff --exit-code - if: always() && steps.install.build == 'success' + if: always() && steps.install.outcome == 'success' && steps.install.build == 'success' # Analyze again after generated files are created to verify that those generated classes don't cause analysis errors - name: Analyze project source (post-build) diff --git a/example/boilerplate_versions/main.dart b/example/boilerplate_versions/main.dart index 10d95dd53..512fce091 100644 --- a/example/boilerplate_versions/main.dart +++ b/example/boilerplate_versions/main.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2021 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/example/builder/main.dart b/example/builder/main.dart index 768664aa9..39ace3813 100644 --- a/example/builder/main.dart +++ b/example/builder/main.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/example/context/main.dart b/example/context/main.dart index c3662f9f6..2f0263995 100644 --- a/example/context/main.dart +++ b/example/context/main.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/example/hooks/main.dart b/example/hooks/main.dart index d3e6abafe..08d329272 100644 --- a/example/hooks/main.dart +++ b/example/hooks/main.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/over_react_component_declaration_test.dart b/test/over_react_component_declaration_test.dart index 617a3fbdb..c0abbd741 100644 --- a/test/over_react_component_declaration_test.dart +++ b/test/over_react_component_declaration_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2016 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/over_react_component_test.dart b/test/over_react_component_test.dart index 0ea0fdf5c..55e5c23b1 100644 --- a/test/over_react_component_test.dart +++ b/test/over_react_component_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2016 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/over_react_dom_test.dart b/test/over_react_dom_test.dart index b693a957d..81daec2a5 100644 --- a/test/over_react_dom_test.dart +++ b/test/over_react_dom_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2018 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/over_react_redux_test.dart b/test/over_react_redux_test.dart index 092ca19be..d3bbaa420 100644 --- a/test/over_react_redux_test.dart +++ b/test/over_react_redux_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2016 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/over_react_util_test.dart b/test/over_react_util_test.dart index 2df6b6719..687ba35d1 100644 --- a/test/over_react_util_test.dart +++ b/test/over_react_util_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2016 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component1/index.dart b/web/component1/index.dart index 8358e4232..9b028b244 100644 --- a/web/component1/index.dart +++ b/web/component1/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component1/src/demos/button/index.dart b/web/component1/src/demos/button/index.dart index fb281d2f7..40f473b4b 100644 --- a/web/component1/src/demos/button/index.dart +++ b/web/component1/src/demos/button/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component1/src/demos/list-group/index.dart b/web/component1/src/demos/list-group/index.dart index e1155f5df..65463e628 100644 --- a/web/component1/src/demos/list-group/index.dart +++ b/web/component1/src/demos/list-group/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component1/src/demos/progress/index.dart b/web/component1/src/demos/progress/index.dart index 4e6c1a929..86b6fdb20 100644 --- a/web/component1/src/demos/progress/index.dart +++ b/web/component1/src/demos/progress/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component1/src/demos/tag/index.dart b/web/component1/src/demos/tag/index.dart index c2e434860..312a51ebd 100644 --- a/web/component1/src/demos/tag/index.dart +++ b/web/component1/src/demos/tag/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component2/index.dart b/web/component2/index.dart index 30afa9354..5267272d1 100644 --- a/web/component2/index.dart +++ b/web/component2/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component2/src/demos/list-group/index.dart b/web/component2/src/demos/list-group/index.dart index e1155f5df..65463e628 100644 --- a/web/component2/src/demos/list-group/index.dart +++ b/web/component2/src/demos/list-group/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component2/src/demos/progress/index.dart b/web/component2/src/demos/progress/index.dart index 4e6c1a929..86b6fdb20 100644 --- a/web/component2/src/demos/progress/index.dart +++ b/web/component2/src/demos/progress/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/component2/src/demos/tag/index.dart b/web/component2/src/demos/tag/index.dart index c2e434860..312a51ebd 100644 --- a/web/component2/src/demos/tag/index.dart +++ b/web/component2/src/demos/tag/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/advanced/examples/flux_implementation/index.dart b/web/flux_to_redux/advanced/examples/flux_implementation/index.dart index d7660454c..38227aff2 100644 --- a/web/flux_to_redux/advanced/examples/flux_implementation/index.dart +++ b/web/flux_to_redux/advanced/examples/flux_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/advanced/examples/influx_implementation/index.dart b/web/flux_to_redux/advanced/examples/influx_implementation/index.dart index 9005673bd..6b4fb4c8b 100644 --- a/web/flux_to_redux/advanced/examples/influx_implementation/index.dart +++ b/web/flux_to_redux/advanced/examples/influx_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/advanced/examples/redux_implementation/index.dart b/web/flux_to_redux/advanced/examples/redux_implementation/index.dart index cdeabd977..8caa8692a 100644 --- a/web/flux_to_redux/advanced/examples/redux_implementation/index.dart +++ b/web/flux_to_redux/advanced/examples/redux_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/simple/examples/flux_implementation/index.dart b/web/flux_to_redux/simple/examples/flux_implementation/index.dart index 17a82c938..c5f5438f1 100644 --- a/web/flux_to_redux/simple/examples/flux_implementation/index.dart +++ b/web/flux_to_redux/simple/examples/flux_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/simple/examples/influx_implementation/index.dart b/web/flux_to_redux/simple/examples/influx_implementation/index.dart index fcc692acf..547972a3d 100644 --- a/web/flux_to_redux/simple/examples/influx_implementation/index.dart +++ b/web/flux_to_redux/simple/examples/influx_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/flux_to_redux/simple/examples/redux_implementation/index.dart b/web/flux_to_redux/simple/examples/redux_implementation/index.dart index e6eadba58..5b95209bf 100644 --- a/web/flux_to_redux/simple/examples/redux_implementation/index.dart +++ b/web/flux_to_redux/simple/examples/redux_implementation/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/over_react_redux/examples/dev_tools/index.dart b/web/over_react_redux/examples/dev_tools/index.dart index 5911dea1f..197724564 100644 --- a/web/over_react_redux/examples/dev_tools/index.dart +++ b/web/over_react_redux/examples/dev_tools/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/over_react_redux/examples/multiple_stores/index.dart b/web/over_react_redux/examples/multiple_stores/index.dart index 42252698b..16713961c 100644 --- a/web/over_react_redux/examples/multiple_stores/index.dart +++ b/web/over_react_redux/examples/multiple_stores/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/web/over_react_redux/examples/simple/index.dart b/web/over_react_redux/examples/simple/index.dart index 274bddc4b..7342c3c0d 100644 --- a/web/over_react_redux/examples/simple/index.dart +++ b/web/over_react_redux/examples/simple/index.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + // Copyright 2020 Workiva Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); From 800a9fc33c279824697f138b95a75f74d9455b24 Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Fri, 5 Feb 2021 08:21:38 -0700 Subject: [PATCH 004/211] Remove build_web_compilers/build_modules overrides + Now that there are tagged releases that work with 2.12 and analyzer 0.40.x --- pubspec.yaml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 4da63ab4f..2f3af6288 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,11 +37,7 @@ dev_dependencies: build_resolvers: ^1.0.5 build_runner: ^1.7.1 build_test: ^0.10.9 - build_web_compilers: - git: - url: https://github.com/aaronlademann-wf/build.git - ref: allow-bazel-worker-nullsafety/build_modules - path: build_web_compilers + build_web_compilers: ^2.5.1 built_value_generator: '>=7.0.0 <9.0.0' dart2_constant: ^1.0.0 dart_dev: ^3.6.4 @@ -58,11 +54,3 @@ workiva: core_checks: version: 1 react_boilerplate: disabled - - -dependency_overrides: - build_modules: - git: - url: https://github.com/aaronlademann-wf/build.git - ref: allow-bazel-worker-nullsafety/build_modules - path: build_modules From 8f3a081604c97347297c23e47e665f336f5380c1 Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Wed, 17 Mar 2021 13:49:36 -0700 Subject: [PATCH 005/211] Copy dart version comment in generated parts --- lib/src/builder/builder.dart | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/src/builder/builder.dart b/lib/src/builder/builder.dart index 9e835752d..b115f93e5 100644 --- a/lib/src/builder/builder.dart +++ b/lib/src/builder/builder.dart @@ -13,6 +13,7 @@ // limitations under the License. import 'dart:async'; +import 'dart:io' show Platform; import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -159,7 +160,8 @@ class OverReactBuilder extends Builder { log.severe('Missing "part \'$expectedPart\';".'); } - await _writePart(buildStep, outputId, outputs); + final dartVersionCommentMatch = RegExp(r'//\s*@dart = (\d+)\.(\d+)').firstMatch(source); + await _writePart(buildStep, outputId, outputs, dartVersionCommentMatch: dartVersionCommentMatch); } else { if (hasOutputPartDirective()) { log.warning('An over_react part directive was found in ${buildStep.inputId.path}, ' @@ -186,10 +188,17 @@ class OverReactBuilder extends Builder { return null; } - static FutureOr _writePart(BuildStep buildStep, AssetId outputId, Iterable outputs) async { + static FutureOr _writePart(BuildStep buildStep, AssetId outputId, Iterable outputs, {RegExpMatch dartVersionCommentMatch}) async { + final isNullSafe = Platform.version.startsWith('2.12') && (int.tryParse(dartVersionCommentMatch?.group(2)) ?? 0) >= 12; final partOf = "'${p.basename(buildStep.inputId.uri.toString())}'"; - final buffer = StringBuffer() + final buffer = StringBuffer(); + + if (!isNullSafe) { + buffer.writeln('// @dart = ${dartVersionCommentMatch.group(1)}.${dartVersionCommentMatch.group(2)}'); + } + + buffer ..writeln('// GENERATED CODE - DO NOT MODIFY BY HAND') ..writeln() ..writeln('// ignore_for_file: deprecated_member_use_from_same_package, unnecessary_null_in_if_null_operators, prefer_null_aware_operators') From fb6d7cee65481cf6f2162266580017f99ad112ff Mon Sep 17 00:00:00 2001 From: Aaron Lademann Date: Wed, 17 Mar 2021 14:21:16 -0700 Subject: [PATCH 006/211] =?UTF-8?q?Let=20the=20consumer=20know=20we=20don?= =?UTF-8?q?=E2=80=99t=20support=20this=20ish=20yet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/builder/builder.dart | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/src/builder/builder.dart b/lib/src/builder/builder.dart index b115f93e5..455ed7184 100644 --- a/lib/src/builder/builder.dart +++ b/lib/src/builder/builder.dart @@ -160,7 +160,10 @@ class OverReactBuilder extends Builder { log.severe('Missing "part \'$expectedPart\';".'); } - final dartVersionCommentMatch = RegExp(r'//\s*@dart = (\d+)\.(\d+)').firstMatch(source); + RegExpMatch dartVersionCommentMatch; + if (source != null) { + dartVersionCommentMatch = RegExp(r'//\s*@dart = (\d+)\.(\d+)').firstMatch(source); + } await _writePart(buildStep, outputId, outputs, dartVersionCommentMatch: dartVersionCommentMatch); } else { if (hasOutputPartDirective()) { @@ -189,7 +192,15 @@ class OverReactBuilder extends Builder { } static FutureOr _writePart(BuildStep buildStep, AssetId outputId, Iterable outputs, {RegExpMatch dartVersionCommentMatch}) async { - final isNullSafe = Platform.version.startsWith('2.12') && (int.tryParse(dartVersionCommentMatch?.group(2)) ?? 0) >= 12; + final dartVersion = Platform.version; + bool nullSafetyIsTurnedOnByDefault = (int.tryParse(RegExp(r'(\d+)\.(\d+)').firstMatch(dartVersion).group(2)) ?? 0) >= 12; + bool isNullSafe = true; + if (dartVersionCommentMatch != null) { + isNullSafe = (int.tryParse(dartVersionCommentMatch?.group(2)) ?? 0) >= 12; + } + if (isNullSafe && nullSafetyIsTurnedOnByDefault) { + throw UnsupportedError('The over_react builder does not yet support null safety. Add a // @dart = 2.7 comment at the top of your file.'); + } final partOf = "'${p.basename(buildStep.inputId.uri.toString())}'"; final buffer = StringBuffer(); From ad10b8bd5a2e6720dab79913a9e98a388918fd56 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 10:40:14 -0700 Subject: [PATCH 007/211] Prep for null-safety --- lib/src/builder/builder.dart | 18 +- lib/src/component/dom_components.dart | 2 +- lib/src/component/ref_util.dart | 186 ----------------- .../over_react_redux/over_react_redux.dart | 2 +- pubspec.yaml | 9 +- test/over_react/component/ref_util_test.dart | 116 +++-------- .../component_type_checking_test.dart | 9 - tool/dart_dev/config.dart | 90 ++++---- web/component2/index.dart | 4 - web/component2/src/demos/ref.dart | 195 ------------------ 10 files changed, 93 insertions(+), 538 deletions(-) diff --git a/lib/src/builder/builder.dart b/lib/src/builder/builder.dart index 455ed7184..086c62589 100644 --- a/lib/src/builder/builder.dart +++ b/lib/src/builder/builder.dart @@ -13,7 +13,7 @@ // limitations under the License. import 'dart:async'; -import 'dart:io' show Platform; +// import 'dart:io' show Platform; import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -192,15 +192,15 @@ class OverReactBuilder extends Builder { } static FutureOr _writePart(BuildStep buildStep, AssetId outputId, Iterable outputs, {RegExpMatch dartVersionCommentMatch}) async { - final dartVersion = Platform.version; - bool nullSafetyIsTurnedOnByDefault = (int.tryParse(RegExp(r'(\d+)\.(\d+)').firstMatch(dartVersion).group(2)) ?? 0) >= 12; + // final dartVersion = Platform.version; + // bool nullSafetyIsTurnedOnByDefault = (int.tryParse(RegExp(r'(\d+)\.(\d+)').firstMatch(dartVersion).group(2)) ?? 0) >= 12; bool isNullSafe = true; - if (dartVersionCommentMatch != null) { - isNullSafe = (int.tryParse(dartVersionCommentMatch?.group(2)) ?? 0) >= 12; - } - if (isNullSafe && nullSafetyIsTurnedOnByDefault) { - throw UnsupportedError('The over_react builder does not yet support null safety. Add a // @dart = 2.7 comment at the top of your file.'); - } + // if (dartVersionCommentMatch != null) { + // isNullSafe = (int.tryParse(dartVersionCommentMatch?.group(2)) ?? 0) >= 12; + // } + // if (isNullSafe && nullSafetyIsTurnedOnByDefault) { + // throw UnsupportedError('The over_react builder does not yet support null safety. Add a // @dart = 2.7 comment at the top of your file.'); + // } final partOf = "'${p.basename(buildStep.inputId.uri.toString())}'"; final buffer = StringBuffer(); diff --git a/lib/src/component/dom_components.dart b/lib/src/component/dom_components.dart index c5904309a..1296fcca0 100644 --- a/lib/src/component/dom_components.dart +++ b/lib/src/component/dom_components.dart @@ -325,7 +325,7 @@ abstract class Dom { /// Returns a new builder that renders a `
` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps main([Map backingMap]) => DomProps(react.main as ReactComponentFactoryProxy, backingMap); + static DomProps main([Map backingMap]) => DomProps(react.htmlMain as ReactComponentFactoryProxy, backingMap); /// Returns a new builder that renders a `` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. diff --git a/lib/src/component/ref_util.dart b/lib/src/component/ref_util.dart index 4077503e6..e84a28e20 100644 --- a/lib/src/component/ref_util.dart +++ b/lib/src/component/ref_util.dart @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'dart:js_util'; - import 'package:over_react/src/component_declaration/component_type_checking.dart'; import 'package:over_react/src/component_declaration/function_component.dart'; import 'package:over_react/src/component_declaration/builder_helpers.dart' as bh; @@ -53,190 +51,6 @@ Ref createRef() { return react_interop.createRef(); } -/// Automatically passes a [Ref] through a component to one of its children. -/// -/// > __NOTE:__ This should only be used to wrap components that extend from `Component2`. -/// -/// __Example 1:__ Forwarding refs to DOM components -/// -/// ```dart -/// import 'dart:html'; -/// import 'package:over_react/over_react.dart'; -/// import 'package:over_react/react_dom.dart' as react_dom; -/// -/// // ---------- Component Definition ---------- -/// -/// final FancyButton = forwardRef((props, ref) { -/// final classes = ClassNameBuilder.fromProps(props) -/// ..add('FancyButton'); -/// -/// return (Dom.button() -/// ..addProps(getPropsToForward(props, onlyCopyDomProps: true)) -/// ..className = classes.toClassName() -/// ..ref = ref -/// )('Click me!'); -/// })(Dom.button); -/// -/// // ---------- Component Consumption ---------- -/// -/// void main() { -/// final ref = createRef(); -/// -/// react_dom.render( -/// (FancyButton() -/// ..ref = ref -/// ..onClick = (_) { -/// print(ref.current.outerHtml); -/// } -/// )(), -/// querySelector('#idOfSomeNodeInTheDom') -/// ); -/// -/// // You can still get a ref directly to the DOM button: -/// final buttonNode = ref.current; -/// } -/// ``` -/// -/// __Example 2:__ Forwarding refs in higher-order components -/// -/// ```dart -/// import 'dart:html'; -/// import 'package:over_react/over_react.dart'; -/// import 'package:over_react/react_dom.dart' as react_dom; -/// -/// // ---------- Component Definitions ---------- -/// -/// final FancyButton = forwardRef((props, ref) { -/// final classes = ClassNameBuilder.fromProps(props) -/// ..add('FancyButton'); -/// -/// return (Dom.button() -/// ..addProps(getPropsToForward(props, onlyCopyDomProps: true)) -/// ..className = classes.toClassName() -/// ..ref = ref -/// )('Click me!'); -/// })(Dom.button); -/// -/// final LogProps = forwardRef((props, ref) { -/// return (_LogProps() -/// ..addProps(props) -/// .._forwardedRef = ref -/// )('Click me!'); -/// })(_LogProps); -/// -/// UiFactory _LogProps = _$_LogProps; -/// -/// mixin LogPropsProps on UiProps { -/// BuilderOnlyUiFactory builder; -/// -/// // Private since we only use this to pass along the value of `ref` to -/// // the return value of forwardRef. -/// // -/// // Consumers can set this private field value using the public `ref` setter. -/// Ref _forwardedRef; -/// } -/// -/// class LogPropsComponent extends UiComponent2 { -/// @override -/// void componentDidUpdate(Map prevProps, _, [__]) { -/// print('old props: $prevProps'); -/// print('new props: $props'); -/// } -/// -/// @override -/// render() { -/// return (props.builder() -/// ..modifyProps(addUnconsumedDomProps) -/// ..ref = props._forwardedRef -/// )(props.children); -/// } -/// } -/// -/// // ---------- Component Consumption ---------- -/// -/// void main() { -/// setClientConfiguration(); -/// final ref = createRef(); -/// -/// react_dom.render( -/// (LogProps() -/// ..builder = FancyButton -/// ..className = 'btn btn-primary' -/// ..ref = ref -/// ..onClick = (_) { -/// print(ref.current.outerHtml); -/// } -/// )(), -/// querySelector('#idOfSomeNodeInTheDom') -/// ); -/// -/// // You can still get a ref directly to the DOM button: -/// final buttonNode = ref.current; -/// } -/// ``` -/// -/// Learn more: . -/// -/// DEPRECATED: use [uiForwardRef] instead. Updating an existing usage can be done -/// like so: -/// -/// ```dart -/// // Before: -/// final FooForwarded = forwardRef((props, ref) { -/// return (Foo() -/// ..addAll(props) -/// ..forwardedRef = ref -/// )(); -/// })(Foo); -/// -/// // After: -/// UiFactory FooForwarded = uiForwardRef((props, ref) { -/// return (Foo() -/// ..addAll(props) -/// ..forwardedRef = ref -/// )(); -/// }, Foo.asForwardRefConfig(displayName: 'FooForwarded')); -/// ``` -@Deprecated('Use uiForwardRef instead. Will be removed in 4.0.0') -UiFactory Function(UiFactory) forwardRef( - Function(TProps props, Ref ref) wrapperFunction, - {String displayName}) { - UiFactory wrapWithForwardRef(UiFactory factory) { - enforceMinimumComponentVersionFor(factory().componentFactory); - - if (displayName == null) { - final componentFactoryType = factory().componentFactory.type; - if (componentFactoryType is String) { - // DomComponent - displayName = componentFactoryType; - } else if (componentFactoryType is Function) { - // JS component factories, Dart function components, Dart composite components - displayName = getProperty(componentFactoryType, 'displayName') as String; - - if (displayName == null) { - final ctor = getProperty(componentFactoryType, 'constructor'); - displayName = (ctor == null ? null : getProperty(ctor, 'name') as String) ?? 'Anonymous'; - } - } - } - - Object wrapProps(Map props, Ref ref) { - return wrapperFunction(factory(props), ref); - } - - ReactComponentFactoryProxy hoc = react_interop.forwardRef(wrapProps, displayName: displayName); - setComponentTypeMeta(hoc.type, isHoc: true, parentType: factory().componentFactory.type); - - TProps forwardedFactory([Map props]) { - return factory(props)..componentFactory = hoc; - } - - return forwardedFactory; - } - - return wrapWithForwardRef; -} - /// Creates a function component capable of forwarding its ref to /// a component it renders. /// diff --git a/lib/src/over_react_redux/over_react_redux.dart b/lib/src/over_react_redux/over_react_redux.dart index e75dc402e..1070d5871 100644 --- a/lib/src/over_react_redux/over_react_redux.dart +++ b/lib/src/over_react_redux/over_react_redux.dart @@ -475,7 +475,7 @@ class ReactJsReactReduxComponentFactoryProxy extends ReactJsContextComponentFact }) : super(jsClass, isProvider: isProvider, isConsumer: isConsumer, shouldConvertDomProps: shouldConvertDomProps); @override - ReactElement build(Map props, [List childrenArgs]) { + ReactElement build(Map props, [List childrenArgs = const []]) { return super.build(_generateReduxJsProps(props), childrenArgs); } diff --git a/pubspec.yaml b/pubspec.yaml index 21bbdf1ab..7bb37f754 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,7 +37,7 @@ dev_dependencies: build_web_compilers: ^2.5.1 built_value_generator: '>=7.0.0 <9.0.0' dart2_constant: ^1.0.0 - dart_dev: ^3.6.4 +# dart_dev: ^3.6.4 dependency_validator: ^1.4.0 glob: ^1.2.0 io: ^0.3.2+1 @@ -47,6 +47,13 @@ dev_dependencies: test: ^1.9.1 yaml: ^2.2.1 +dependency_overrides: + react: + git: + url: https://github.com/Workiva/react-dart.git + ref: null-safety-manual + + workiva: core_checks: version: 1 diff --git a/test/over_react/component/ref_util_test.dart b/test/over_react/component/ref_util_test.dart index 4673a1c83..779d7a2a6 100644 --- a/test/over_react/component/ref_util_test.dart +++ b/test/over_react/component/ref_util_test.dart @@ -24,32 +24,20 @@ import 'package:over_react/src/component/dom_components.dart'; import '../../test_util/test_util.dart'; import '../component/fixtures/basic_child_component.dart'; -import 'fixtures/basic_ui_component.dart'; part 'ref_util_test.over_react.g.dart'; // ignore: uri_has_not_been_generated main() { - group('forward ref -', () { - test('errors when wrapping a UiComponent', () { - expect( - () => forwardRef((props, ref) { - return (BasicUiComponent()..ref = ref)(); - })(BasicUiComponent), - throwsArgumentError); - }); - - commonRefForwardingTests(); - }); group('uiForwardRef -', () { group('fundamentally behaves the same as `forwardRef', () { - commonRefForwardingTests(useUiForwardRef: true); + commonRefForwardingTests(); }); group('on a function component child', () { testForwardRefWith(BasicChild, verifyRefValue: (ref) { expect(ref, TypeMatcher()); - }, useUiForwardRef: true); + }); group('using the factory\'s `asForwardRefConfig` syntax', () { test('- sets displayName on the rendered component as expected', () { @@ -123,30 +111,18 @@ main() { } @isTestGroup -void commonRefForwardingTests({bool useUiForwardRef = false}) { +void commonRefForwardingTests() { UiFactory getFactoryForBasic({ String displayName, }) { - if (useUiForwardRef) { - if (displayName == null) { - return uiForwardRef((props, ref) { - return (Basic()..ref = ref)(props.children); - }, Basic.asForwardRefConfig()); - } else { - return uiForwardRef((props, ref) { - return (Basic()..ref = ref)(props.children); - }, Basic.asForwardRefConfig(displayName: displayName)); - } + if (displayName == null) { + return uiForwardRef((props, ref) { + return (Basic()..ref = ref)(props.children); + }, Basic.asForwardRefConfig()); } else { - if (displayName == null) { - return forwardRef((props, ref) { - return (Basic()..ref = ref)(props.children); - })(Basic); - } else { - return forwardRef((props, ref) { - return (Basic()..ref = ref)(props.children); - }, displayName: displayName)(Basic); - } + return uiForwardRef((props, ref) { + return (Basic()..ref = ref)(props.children); + }, Basic.asForwardRefConfig(displayName: displayName)); } } @@ -155,26 +131,14 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { }) { ReactElement div(dynamic ref, dynamic children) => (Dom.div()..ref = ref)(children); - if (useUiForwardRef) { - if (displayName == null) { - return uiForwardRef((props, ref) { - return div(ref, props.children); - }, Dom.div.asForwardRefConfig()); - } else { - return uiForwardRef((props, ref) { - return div(ref, props.children); - }, Dom.div.asForwardRefConfig(displayName: displayName)); - } + if (displayName == null) { + return uiForwardRef((props, ref) { + return div(ref, props.children); + }, Dom.div.asForwardRefConfig()); } else { - if (displayName == null) { - return forwardRef((props, ref) { - return div(ref, props.children); - })(Dom.div); - } else { - return forwardRef((props, ref) { - return div(ref, props.children); - }, displayName: displayName)(Dom.div); - } + return uiForwardRef((props, ref) { + return div(ref, props.children); + }, Dom.div.asForwardRefConfig(displayName: displayName)); } } @@ -182,7 +146,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { group('on a component with a dom component child', () { testForwardRefWith(Dom.span, verifyRefValue: (ref) { expect(ref, TypeMatcher()); - }, useUiForwardRef: useUiForwardRef); + }); test('- while consuming the `DomProps` props class', () { UiFactory DivForwarded = getFactoryForDiv(); @@ -201,11 +165,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { final refObject = createRef(); final vDomElement = (DivForwarded()..ref = refObject)(); - if (useUiForwardRef) { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), ''); - } else { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'displayName'), 'div'); - } + expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), ''); }); test('when displayName argument is passed to the config constructor', () { @@ -215,11 +175,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { final vDomElement = (DivForwarded()..ref = refObject)(); - if (useUiForwardRef) { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), displayName); - } else { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'displayName'), displayName); - } + expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), displayName); }); }); @@ -237,7 +193,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { group('on a component with a dart component child', () { testForwardRefWith(Basic, verifyRefValue: (ref) { expect(ref, TypeMatcher()); - }, useUiForwardRef: useUiForwardRef); + }); group('- sets displayName on the rendered component as expected', () { test('when displayName argument is not passed to forwardRef', () { @@ -246,11 +202,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { final Ref refObject = createRef(); final vDomElement = (BasicForwarded()..ref = refObject)(); - if (useUiForwardRef) { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), ''); - } else { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'displayName'), 'Basic'); - } + expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), ''); }); test('when displayName argument is passed to the config constructor', () { @@ -259,11 +211,7 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { final Ref refObject = createRef(); final vDomElement = (BasicForwarded()..ref = refObject)(); - if (useUiForwardRef) { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), displayName); - } else { - expect(getProperty(getProperty(vDomElement.type, 'render'), 'displayName'), displayName); - } + expect(getProperty(getProperty(vDomElement.type, 'render'), 'name'), displayName); }); }); @@ -283,19 +231,13 @@ void commonRefForwardingTests({bool useUiForwardRef = false}) { const displayName = 'AVerySpecificDisplayName'; void testForwardRefWith(dynamic factory, - {void Function(dynamic refValue) verifyRefValue, bool useUiForwardRef = false}) { + {void Function(dynamic refValue) verifyRefValue}) { test('- passes a ref through the parent to its child', () { - UiFactory BasicForwarded = useUiForwardRef - ? uiForwardRef((props, ref) { - return (factory() - ..ref = ref - ..id = props.childId)(); - }, Basic.asForwardRefConfig()) - : forwardRef((props, ref) { - return (factory() - ..ref = ref - ..id = props.childId)(); - })(Basic); + final BasicForwarded = uiForwardRef((props, ref) { + return (factory() + ..ref = ref + ..id = props.childId)(); + }, Basic.asForwardRefConfig()); final Ref refObject = createRef(); diff --git a/test/over_react/component_declaration/component_type_checking_test.dart b/test/over_react/component_declaration/component_type_checking_test.dart index 5a16740f2..ad370bd62 100644 --- a/test/over_react/component_declaration/component_type_checking_test.dart +++ b/test/over_react/component_declaration/component_type_checking_test.dart @@ -500,19 +500,10 @@ testComponentTypeChecking({ group('a higher-order component created by', () { if (TestA().componentFactory.type.dartComponentVersion == '1') { - test('forwardRef', () { - expect(() => forwardRef((props, ref) => null)(TestA), throwsArgumentError); - }); - test('connect', () { expect(() => connect(mapStateToProps: (state) => {})(TestA), throwsArgumentError); }); } else { - test('forwardRef', () { - final hocFactory = forwardRef((props, ref) => null)(TestA); - expect(isComponentOfType(hocFactory()(), TestA), isTrue); - }); - test('connect', () { final hocFactory = connect(mapStateToProps: (state) => {})(TestA); expect(isComponentOfType(hocFactory()(), TestA), isTrue); diff --git a/tool/dart_dev/config.dart b/tool/dart_dev/config.dart index 84a51e64e..e704ffaf9 100644 --- a/tool/dart_dev/config.dart +++ b/tool/dart_dev/config.dart @@ -1,47 +1,47 @@ -// Copyright 2016 Workiva Inc. +// // Copyright 2016 Workiva Inc. +// // +// // Licensed under the Apache License, Version 2.0 (the "License"); +// // you may not use this file except in compliance with the License. +// // You may obtain a copy of the License at +// // +// // http://www.apache.org/licenses/LICENSE-2.0 +// // +// // Unless required by applicable law or agreed to in writing, software +// // distributed under the License is distributed on an "AS IS" BASIS, +// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// // See the License for the specific language governing permissions and +// // limitations under the License. // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// import 'package:dart_dev/dart_dev.dart'; +// import 'package:glob/glob.dart'; // -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:dart_dev/dart_dev.dart'; -import 'package:glob/glob.dart'; - -final config = { - 'analyze': AnalyzeTool() - ..include = [ - Glob('lib/**.dart'), - Glob('test/**.dart'), - Glob('tool/**.dart'), - ], - 'format': FormatTool() - ..formatterArgs = ['--line-length=100'] - ..exclude = [ - // We don't format most of this repo with dartfmt, yet. - Glob('app/**'), - Glob('example/**'), - Glob('lib/*'), - Glob('lib/src/builder/builder.dart'), - Glob('lib/src/builder/util.dart'), - Glob('lib/src/component/**'), - Glob('lib/src/component_declaration/**'), - Glob('lib/src/over_react_redux/**'), - Glob('lib/src/util/**'), - Glob('test/**'), - Glob('tools/analyzer_plugin/**'), - Glob('test_fixtures/**'), - Glob('web/**'), - ], - 'test': TestTool() - ..buildArgs = [ - '--delete-conflicting-outputs', - ], -}; +// final config = { +// 'analyze': AnalyzeTool() +// ..include = [ +// Glob('lib/**.dart'), +// Glob('test/**.dart'), +// Glob('tool/**.dart'), +// ], +// 'format': FormatTool() +// ..formatterArgs = ['--line-length=100'] +// ..exclude = [ +// // We don't format most of this repo with dartfmt, yet. +// Glob('app/**'), +// Glob('example/**'), +// Glob('lib/*'), +// Glob('lib/src/builder/builder.dart'), +// Glob('lib/src/builder/util.dart'), +// Glob('lib/src/component/**'), +// Glob('lib/src/component_declaration/**'), +// Glob('lib/src/over_react_redux/**'), +// Glob('lib/src/util/**'), +// Glob('test/**'), +// Glob('tools/analyzer_plugin/**'), +// Glob('test_fixtures/**'), +// Glob('web/**'), +// ], +// 'test': TestTool() +// ..buildArgs = [ +// '--delete-conflicting-outputs', +// ], +// }; diff --git a/web/component2/index.dart b/web/component2/index.dart index 5267272d1..24941114c 100644 --- a/web/component2/index.dart +++ b/web/component2/index.dart @@ -89,8 +89,4 @@ void main() { react_dom.render(ListExample()(), querySelector('$demoMountNodeSelectorPrefix--list-component')); react_dom.render(NumExample()(), querySelector('$demoMountNodeSelectorPrefix--num-component')); react_dom.render(StringExample()(), querySelector('$demoMountNodeSelectorPrefix--string-component')); - react_dom.render( - (RefDemoContainer())(), - querySelector('$demoMountNodeSelectorPrefix--forwardRef'), - ); } diff --git a/web/component2/src/demos/ref.dart b/web/component2/src/demos/ref.dart index 8d80e449f..1b36bcd5d 100644 --- a/web/component2/src/demos/ref.dart +++ b/web/component2/src/demos/ref.dart @@ -1,6 +1,3 @@ -// ignore_for_file: deprecated_member_use_from_same_package -import 'dart:html'; - import 'package:over_react/over_react.dart'; // ignore: uri_has_not_been_generated @@ -112,195 +109,3 @@ final Foo2 = uiForwardRef( }, _$Foo2Config, // ignore: undefined_identifier ); - -//----------------------------------------------------------------------------// -//----------------------------------------------------------------------------// -// forwardRef Examples (deprecated) -//----------------------------------------------------------------------------// -//----------------------------------------------------------------------------// - -//----------------------------------------------------------------------------// -// ### Example 1: Exposing inner refs in class components: -//----------------------------------------------------------------------------// -UiFactory LogPropsHoc = forwardRef((props, ref) { - return (_Log() - ..addProps(props) - .._forwardedRef = ref - )(); -}, displayName: 'LogProps')(_Log); - -UiFactory _Log = castUiFactory(_$_Log); // ignore: undefined_identifier - -mixin LogProps on UiProps { - BuilderOnlyUiFactory builder; - - // Private since we only use this to pass along the value of `ref` to - // the return value of forwardRef. - // - // Consumers can set this private field value using the public `ref` setter. - dynamic _forwardedRef; -} - -// ignore: unused_element -class _LogComponent extends UiComponent2 { - @override - void componentDidUpdate(Map prevProps, _, [__]) { - print('old props: $prevProps'); - print('new props: $props'); - } - - @override - render() { - return Dom.div()( - (props.builder() - ..modifyProps(addUnconsumedDomProps) - ..ref = props._forwardedRef - )(props.children), - ); - } -} - -//----------------------------------------------------------------------------// -// ### Example 2: Exposing inner refs in functional components: -//----------------------------------------------------------------------------// -UiFactory LoggingFunctionWrapper = forwardRef((props, ref) { - print('LoggingFunctionWrapper rendered!'); - - return (Baz() - ..addProps(props) - ..builder = props.builder - .._forwardedRef = ref - )(); -}, displayName: 'LoggingFunctionWrapper')(Baz); - -mixin BazProps on UiProps { - BuilderOnlyUiFactory builder; - - // Private since we only use this to pass along the value of `ref` to - // the return value of forwardRef. - // - // Consumers can set this private field value using the public `ref` setter. - dynamic _forwardedRef; -} - -final Baz = uiFunction( - (props) { - return ((props.builder() - ..addProps(getPropsToForward(props, onlyCopyDomProps: true)) - ..ref = props._forwardedRef - )(props.children)); - }, - _$BazConfig, // ignore: undefined_identifier -); - -// -------------------------------- Demo Display Logic -------------------------------- - -mixin RefDemoProps on UiProps {} - -UiFactory RefDemoContainer = uiFunction( - (props) { - // `uiForwardRef` Refs - final fancyButtonUiForwardRef = createRef(); - final fancyButtonWithLoggingReg = createRef(); - final fooInputRef = createRef(); - final foo2InputRef = createRef(); - - // `forwardRef` Refs - final fancyButtonNodeRef = createRef(); - final fancyFunctionalButtonNodeRef = createRef(); - - return ((Dom.div()..style = {'padding': 10})( - (RefDemoSection()..sectionTitle = 'uiForwardRef Demos')( - (RefDemoHoc()..demoTitle = 'Basic `uiForwardRef`')( - (FancyButton() - ..className = 'btn btn-primary' - ..ref = fancyButtonUiForwardRef - ..onClick = (_) => printButtonOuterHtml(fancyButtonUiForwardRef) - )(), - ), - (RefDemoHoc()..demoTitle = '`uiForwardRef` wrapped in HOC')( - (FancyButtonWithLogging() - ..className = 'btn btn-success' - ..ref = fancyButtonWithLoggingReg - ..onClick = (_) => printButtonOuterHtml(fancyButtonUiForwardRef) - )(), - ), - (RefDemoHoc()..demoTitle = '`uiForwardRef` wrapping a class (option 1)')( - (Foo() - ..ref = fooInputRef - ..onChange = (e) => print('Foo Input Ref: ${e.target.value}') - )(), - ), - (RefDemoHoc()..demoTitle = '`uiForwardRef` wrapping a class (option 2)')( - (Foo2() - ..anExampleAdditionalProp = 'This additional prop logs on renders!' - ..ref = foo2InputRef - ..onChange = (e) => print('Foo2 Input Ref: ${e.target.value}') - )(), - ), - ), - (RefDemoSection()..sectionTitle = 'forwardRef (deprecated) Demos')( - (RefDemoHoc()..demoTitle = '`forwardRef` with class component')( - (LogPropsHoc() - ..builder = FancyButton - ..ref = fancyButtonNodeRef - ..className = 'btn btn-primary' - ..onClick = (_) => printButtonOuterHtml(fancyButtonNodeRef) - )(), - ), - (RefDemoHoc()..demoTitle = '`forwardRef` with function component')( - (LoggingFunctionWrapper() - ..builder = FancyButton - ..className = 'btn btn-success' - ..ref = fancyFunctionalButtonNodeRef - ..onClick = (_) { - printButtonOuterHtml(fancyFunctionalButtonNodeRef); - } - )(), - ), - ), - )); - }, - _$RefDemoContainerConfig, // ignore: undefined_identifier -); - -void printButtonOuterHtml(Ref buttonRef) { - print('this button outerHTML: ${buttonRef.current.outerHtml}'); -} - -mixin RefDemoSectionProps on UiProps { - String sectionTitle; -} - -UiFactory RefDemoSection = uiFunction( - (props) { - return (Fragment()( - (Dom.h3()..style = {'color': 'gray', 'borderBottom': '1px solid gray', 'marginTop': 10})( - props.sectionTitle, - ), - (Dom.div() - ..style = { - 'display': 'flex', - 'flexWrap': 'wrap', - } - )( - props.children, - ), - )); - }, - _$RefDemoSectionConfig, // ignore: undefined_identifier -); - -mixin RefDemoHocProps on UiProps { - String demoTitle; -} - -UiFactory RefDemoHoc = uiFunction( - (props) { - return ((Dom.div()..style = {'flex': '0 50%', 'width': '100%', 'marginTop': 10})( - Dom.h4()(props.demoTitle), - props.children, - )); - }, - _$RefDemoHocConfig, // ignore: undefined_identifier -); From 15cb82305596daeb4cf675830d136593a0611909 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 10:40:22 -0700 Subject: [PATCH 008/211] Generate files --- .../redux_component_test/test_reducer.g.dart | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/over_react/component_declaration/redux_component_test/test_reducer.g.dart b/test/over_react/component_declaration/redux_component_test/test_reducer.g.dart index b4adebfa4..8afa9e060 100644 --- a/test/over_react/component_declaration/redux_component_test/test_reducer.g.dart +++ b/test/over_react/component_declaration/redux_component_test/test_reducer.g.dart @@ -44,12 +44,8 @@ class _$BaseState extends BaseState { (new BaseStateBuilder()..update(updates)).build(); _$BaseState._({this.count1, this.count2}) : super._() { - if (count1 == null) { - throw new BuiltValueNullFieldError('BaseState', 'count1'); - } - if (count2 == null) { - throw new BuiltValueNullFieldError('BaseState', 'count2'); - } + BuiltValueNullFieldError.checkNotNull(count1, 'BaseState', 'count1'); + BuiltValueNullFieldError.checkNotNull(count2, 'BaseState', 'count2'); } @override @@ -95,9 +91,10 @@ class BaseStateBuilder implements Builder { BaseStateBuilder(); BaseStateBuilder get _$this { - if (_$v != null) { - _count1 = _$v.count1; - _count2 = _$v.count2; + final $v = _$v; + if ($v != null) { + _count1 = $v.count1; + _count2 = $v.count2; _$v = null; } return this; @@ -105,9 +102,7 @@ class BaseStateBuilder implements Builder { @override void replace(BaseState other) { - if (other == null) { - throw new ArgumentError.notNull('other'); - } + ArgumentError.checkNotNull(other, 'other'); _$v = other as _$BaseState; } @@ -118,7 +113,12 @@ class BaseStateBuilder implements Builder { @override _$BaseState build() { - final _$result = _$v ?? new _$BaseState._(count1: count1, count2: count2); + final _$result = _$v ?? + new _$BaseState._( + count1: BuiltValueNullFieldError.checkNotNull( + count1, 'BaseState', 'count1'), + count2: BuiltValueNullFieldError.checkNotNull( + count2, 'BaseState', 'count2')); replace(_$result); return _$result; } From e6aece88f441a6d06a8dd94d7d626e5fb670c373 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 10:40:28 -0700 Subject: [PATCH 009/211] Add some hints --- lib/src/builder/codegen/accessors_generator.dart | 2 +- lib/src/component/_deprecated/abstract_transition.dart | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/builder/codegen/accessors_generator.dart b/lib/src/builder/codegen/accessors_generator.dart index 2849191e7..bc1474115 100644 --- a/lib/src/builder/codegen/accessors_generator.dart +++ b/lib/src/builder/codegen/accessors_generator.dart @@ -48,7 +48,7 @@ abstract class TypedMapAccessorsGenerator extends BoilerplateDeclarationGenerato TypedMapType get type; - BoilerplateTypedMapMember get member; + BoilerplateTypedMapMember/*!*/ get member; TypedMapNames get names; diff --git a/lib/src/component/_deprecated/abstract_transition.dart b/lib/src/component/_deprecated/abstract_transition.dart index 8487f8663..51c1226e7 100644 --- a/lib/src/component/_deprecated/abstract_transition.dart +++ b/lib/src/component/_deprecated/abstract_transition.dart @@ -123,13 +123,13 @@ abstract class AbstractTransitionComponent true; + bool/*!*/ get hasTransition => true; /// Whether the Element returned by [getTransitionDomNode] will have a transition event when showing. bool get hasTransitionIn => hasTransition && transitionInCount > 0; @@ -148,7 +148,7 @@ abstract class AbstractTransitionComponent props.transitionOutCount ?? props.transitionCount ?? 1; /// The duration that can elapse before a transition timeout occurs. - Duration get transitionTimeout => const Duration(seconds: 1); + Duration/*!*/ get transitionTimeout => const Duration(seconds: 1); /// Timer used to determine if a transition timeout has occurred. Timer _transitionEndTimer; From c3172108323703b89b0cffbf577d543166287f64 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 12:25:37 -0700 Subject: [PATCH 010/211] Clean up some code to be easier to make null-safe --- .../component_declaration/component_base.dart | 12 +++--------- lib/src/util/pretty_print.dart | 18 +++++++++--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/src/component_declaration/component_base.dart b/lib/src/component_declaration/component_base.dart index da81bd566..39162b54b 100644 --- a/lib/src/component_declaration/component_base.dart +++ b/lib/src/component_declaration/component_base.dart @@ -373,29 +373,23 @@ class _WarnOnModify extends MapView { //Used to customize warning based on whether the data is props or state bool isProps; - String message; - _WarnOnModify(Map componentData, this.isProps) : super(componentData); @override operator []=(K key, V value) { - if (isProps) { - message = - ''' + final message = isProps + ? ''' props["$key"] was updated incorrectly. Never mutate this.props directly, as it can cause unexpected behavior; props must be updated only by passing in new values when re-rendering this component. This will throw in UiComponentV2 (to be released as part of the React 16 upgrade). - '''; - } else { - message = ''' + : ''' state["$key"] was updated incorrectly. Never mutate this.state directly, as it can cause unexpected behavior; state must be updated only via setState. This will throw in UiComponentV2 (to be released as part of the React 16 upgrade). '''; - } super[key] = value; ValidationUtil.warn(unindent(message)); } diff --git a/lib/src/util/pretty_print.dart b/lib/src/util/pretty_print.dart index 499768aee..29847effe 100644 --- a/lib/src/util/pretty_print.dart +++ b/lib/src/util/pretty_print.dart @@ -71,17 +71,16 @@ String _prettyObj(Object obj) { } } else if (obj is Map) { final namespacedKeys = >{}; - final otherKeys = []; + final otherKeys = []; - obj.keys.forEach((dynamic key) { + obj.keys.forEach((key) { const namespaceSeparator = '.'; if (key is String && key.contains(namespaceSeparator)) { var index = key.indexOf(namespaceSeparator); var namespace = key.substring(0, index); var subkey = key.substring(index); - namespacedKeys[namespace] ??= []; - namespacedKeys[namespace].add(subkey); + namespacedKeys.putIfAbsent(namespace, () => []).add(subkey); } else { otherKeys.add(key); } @@ -89,7 +88,10 @@ String _prettyObj(Object obj) { final pairs = []; - pairs.addAll(namespacedKeys.keys.map((namespace) { + pairs.addAll(namespacedKeys.entries.map((entry) { + final namespace = entry.key; + final subkeys = entry.value; + String renderSubKey(String subkey) { var key = '$namespace$subkey'; var value = obj[key]; @@ -97,16 +99,14 @@ String _prettyObj(Object obj) { return '$subkey: ' + _prettyObj(value); } - Iterable subkeys = namespacedKeys[namespace]; - return '$namespace…\n' + _indentString(subkeys.map(renderSubKey).map((pair) => pair + ',\n').join()); })); - pairs.addAll(otherKeys.map((dynamic key) { + pairs.addAll(otherKeys.map((key) { return '$key: ' + _prettyObj(obj[key]) + ','; })); - final RegExp trailingComma = RegExp(r'\s*,\s*$'); + final trailingComma = RegExp(r'\s*,\s*$'); if (pairs.length > _maxKeyValuePairsPerLine || pairs.any((pair) => pair.contains('\n'))) { var inner = _indentString(pairs.join('\n')).replaceFirst(trailingComma, ''); From ceaebc91ef8cc5d329434f98a283c19e39b629c7 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 12:29:27 -0700 Subject: [PATCH 011/211] Use null safety tool to migrate most non-builder code in lib, adding hints but not applying the migration Also excludes: - lib/src/component - lib/src/over_react_redux/devtools/ - lib/src/over_react_redux/over_react_flux.dart --- lib/react_dom.dart | 2 +- .../component_declaration/component_base.dart | 22 ++++--- .../component_base_2.dart | 8 +-- .../component_type_checking.dart | 2 +- .../component_declaration/flux_component.dart | 6 +- .../over_react_redux/hooks/use_selector.dart | 21 ++++--- .../over_react_redux/over_react_redux.dart | 63 ++++++++++--------- lib/src/util/css_value_util.dart | 5 +- lib/src/util/map_util.dart | 14 ++--- lib/src/util/react_wrappers.dart | 2 +- 10 files changed, 75 insertions(+), 70 deletions(-) diff --git a/lib/react_dom.dart b/lib/react_dom.dart index 7f7b92450..fed37d93b 100644 --- a/lib/react_dom.dart +++ b/lib/react_dom.dart @@ -55,6 +55,6 @@ dynamic render(ReactElement element, Element mountNode) { /// * Returns `true` if a `Component` was mounted in the [mountNode]. /// /// > Proxies [react_dom.unmountComponentAtNode]. -bool unmountComponentAtNode(Element mountNode) { +bool/*!*/ unmountComponentAtNode(Element mountNode) { return react_dom.unmountComponentAtNode(mountNode) as bool; } diff --git a/lib/src/component_declaration/component_base.dart b/lib/src/component_declaration/component_base.dart index 39162b54b..1a0a75f3c 100644 --- a/lib/src/component_declaration/component_base.dart +++ b/lib/src/component_declaration/component_base.dart @@ -91,7 +91,7 @@ ReactDartComponentFactoryProxy registerAbstractComponent(Type abstractComponentC /// /// For use in wrapping existing Maps in typed getters and setters, and for creating React components /// via a fluent-style builder interface. -typedef TProps UiFactory([Map backingProps]); +typedef TProps/*!*/ UiFactory([Map backingProps]); extension UiFactoryHelpers on UiFactory { /// Generates the configuration necessary to construct a UiFactory while invoking @@ -154,7 +154,7 @@ typedef TProps BuilderOnlyUiFactory(); /// /// __Deprecated.__ Use `UiComponent2` instead. Will be removed in the `4.0.0` release. @Deprecated('4.0.0') -abstract class UiComponent extends react.Component with DisposableManagerProxy { +abstract class UiComponent extends react.Component with DisposableManagerProxy { /// The props for the non-forwarding props defined in this component. Iterable get consumedProps => null; @@ -574,7 +574,7 @@ abstract class UiProps extends MapBase } /// Returns a new component with this builder's [props] and the specified [children]. - ReactElement build([dynamic children]) { + ReactElement/*!*/ build([dynamic children]) { assert(_validateChildren(children)); _assertComponentFactoryIsNotNull(); @@ -650,6 +650,7 @@ abstract class UiProps extends MapBase return true; } + // fixme null-safety: nullable or `late`? ReactComponentFactoryProxy componentFactory; /// An unmodifiable map view of the default props for this component brought @@ -785,17 +786,17 @@ class ConsumedProps { /// Rich views of prop declarations. /// /// This includes string keys, and required prop validation related fields. - final List props; + final List/*!*/ props; /// Top-level accessor of string keys of props stored in [props]. - final List keys; + final List/*!*/ keys; const ConsumedProps(this.props, this.keys); } abstract class AccessorMeta { - List get fields; - List get keys; + List/*!*/ get fields; + List/*!*/ get keys; } /// Metadata for the prop fields declared in a specific props class-- @@ -831,11 +832,11 @@ class PropsMeta implements ConsumedProps, AccessorMeta { /// /// This includes string keys, and required prop validation related fields. @override - final List fields; + final List/*!*/ fields; /// Top-level accessor of string keys of props stored in [fields]. @override - final List keys; + final List/*!*/ keys; const PropsMeta({this.fields, this.keys}); @@ -856,7 +857,7 @@ class PropsMeta implements ConsumedProps, AccessorMeta { ); @override - List get props => fields; + List/*!*/ get props => fields; @override String toString() => 'PropsMeta:$keys'; @@ -911,6 +912,7 @@ abstract class _AccessorMetaCollection Related: [UiStatefulComponent2] -abstract class UiComponent2 extends react.Component2 +abstract class UiComponent2 extends react.Component2 with DisposableManagerProxy, GeneratedClass implements UiComponent { // *************************************************************************** @@ -170,7 +170,7 @@ abstract class UiComponent2 extends react.Component2 /// Required to properly instantiate the generic [TProps] class. @override @toBeGenerated - TProps typedPropsFactory(Map propsMap)=> throw UngeneratedError(member: #typedPropsFactory); + TProps typedPropsFactory(Map/*!*/ propsMap)=> throw UngeneratedError(member: #typedPropsFactory); /// Returns a typed props object backed by the specified [propsMap]. /// @@ -355,7 +355,7 @@ abstract class UiComponent2 extends react.Component2 /// the `@Props` class for this component, and not any inherited props. Also, [propsMeta] is not /// available. @override - Iterable get consumedProps => $defaultConsumedProps; + Iterable/*!*/ get consumedProps => $defaultConsumedProps; /// A collection of metadata for the prop fields in all prop mixins used by this component's /// generated props class. @@ -654,7 +654,7 @@ mixin UiStatefulMixin2 on UiComp /// /// Required to properly instantiate the generic [TState] class. @toBeGenerated - TState typedStateFactory(Map stateMap) => throw UngeneratedError(member: #typedStateFactory, + TState typedStateFactory(Map/*!*/ stateMap) => throw UngeneratedError(member: #typedStateFactory, message: GeneratedErrorMessages.typedStateFactory); /// Returns a typed state object backed by the specified [stateMap]. diff --git a/lib/src/component_declaration/component_type_checking.dart b/lib/src/component_declaration/component_type_checking.dart index f967faccb..29509ed2e 100644 --- a/lib/src/component_declaration/component_type_checking.dart +++ b/lib/src/component_declaration/component_type_checking.dart @@ -377,7 +377,7 @@ bool isComponentOfType(ReactElement instance, dynamic typeAlias, /// /// > Related: [isComponentOfType] bool isValidElementOfType(dynamic instance, dynamic typeAlias) { - return isValidElement(instance) && isComponentOfType(instance as ReactElement, typeAlias); + return isValidElement(instance) && isComponentOfType(instance as ReactElement/*!*/, typeAlias); } /// Validates that a [ReactComponentFactoryProxy]'s component is not `Component` diff --git a/lib/src/component_declaration/flux_component.dart b/lib/src/component_declaration/flux_component.dart index 61cb2f352..81a38d414 100644 --- a/lib/src/component_declaration/flux_component.dart +++ b/lib/src/component_declaration/flux_component.dart @@ -274,7 +274,7 @@ mixin _FluxComponentMixin on component_base.UiCompon /// /// Override to set up custom listener behavior. @protected - void listenToStoreForRedraw(Store store) { + void listenToStoreForRedraw(Store/*!*/ store) { _validateStoreDisposalState(store); _subscriptions.add(store.listen(handleRedrawOn)); } @@ -324,7 +324,7 @@ mixin _FluxComponentMixin on component_base.UiCompon /// /// @override /// redrawOn() => [store.tasks, store.users]; - List redrawOn() { + List redrawOn() { final store = props.store; return store is Store ? [store] : []; } @@ -338,7 +338,7 @@ mixin _FluxComponentMixin on component_base.UiCompon /// If possible, however, [redrawOn] should be used instead of this in order /// to avoid keeping additional state within this component and manually /// managing redraws. - Map getStoreHandlers() { + Map getStoreHandlers() { return {}; } diff --git a/lib/src/over_react_redux/hooks/use_selector.dart b/lib/src/over_react_redux/hooks/use_selector.dart index 0482b8a38..f95cd35e6 100644 --- a/lib/src/over_react_redux/hooks/use_selector.dart +++ b/lib/src/over_react_redux/hooks/use_selector.dart @@ -122,16 +122,16 @@ import 'package:react/react_client/react_interop.dart' show ReactContext; /// parameterize it with. /// /// > Related: [useDispatch] -TValue useSelector(TValue Function(TReduxState state) selector, [ +TValue/*!*/ useSelector(TValue Function(TReduxState/*!*/ state) selector, [ bool Function(TValue tNextValue, TValue tPrevValue) equalityFn, ]) { - ReactInteropValue jsSelector(ReactInteropValue jsState) => wrapInteropValue(selector(unwrapInteropValue(jsState))); + ReactInteropValue jsSelector(ReactInteropValue jsState) => wrapInteropValue(selector(unwrapInteropValue(jsState) as TReduxState)); _JsReduxStateEqualityFn jsEqualityFn = equalityFn == null ? null : allowInterop((nextJsValue, prevJsValue) => - equalityFn(unwrapInteropValue(nextJsValue), unwrapInteropValue(prevJsValue))); + equalityFn(unwrapInteropValue(nextJsValue) as TValue, unwrapInteropValue(prevJsValue) as TValue)); - return unwrapInteropValue(_jsUseSelector(allowInterop(jsSelector), jsEqualityFn)); + return unwrapInteropValue(_jsUseSelector(allowInterop(jsSelector), jsEqualityFn)) as TValue; } @JS('ReactRedux.useSelector') @@ -197,18 +197,19 @@ external ReactInteropValue _jsUseSelector(_JsSelectorFn selector, [_JsReduxState /// ``` _SelectorFnHook createSelectorHook([Context context]) { final jsHook = _jsCreateSelectorHook(context?.jsThis ?? JsReactRedux.ReactReduxContext); - TValue dartHook(TValue Function(TReduxState state) selector, [ - bool Function(TValue tNextValue, TValue tPrevValue) equalityFn, + TValue/*!*/ dartHook(TValue Function(TReduxState/*!*/ state) selector, [ + bool Function(TValue/*!*/ tNextValue, TValue/*!*/ tPrevValue) equalityFn, ]) { - ReactInteropValue jsSelector(ReactInteropValue jsState) => wrapInteropValue(selector(unwrapInteropValue(jsState))); + ReactInteropValue jsSelector(ReactInteropValue jsState) => wrapInteropValue(selector(unwrapInteropValue(jsState) as TReduxState)); _JsReduxStateEqualityFn jsEqualityFn = equalityFn == null ? null : allowInterop((nextJsValue, prevJsValue) => - equalityFn(unwrapInteropValue(nextJsValue), unwrapInteropValue(prevJsValue))); + equalityFn(unwrapInteropValue(nextJsValue) as TValue, unwrapInteropValue(prevJsValue) as TValue)); - return unwrapInteropValue(jsHook(allowInterop(jsSelector), jsEqualityFn)); + return unwrapInteropValue(jsHook(allowInterop(jsSelector), jsEqualityFn)) as TValue; } + // FIXME null-safety remove unnecessary cast here added by migration tool return dartHook; } @@ -222,7 +223,7 @@ external _JsSelectorFnHook _jsCreateSelectorHook(ReactContext context); typedef _JsSelectorFn = ReactInteropValue Function(ReactInteropValue jsState); typedef _JsReduxStateEqualityFn = bool Function(ReactInteropValue nextJsValue, ReactInteropValue prevJsValue); typedef _JsSelectorFnHook = ReactInteropValue Function(_JsSelectorFn selector, [_JsReduxStateEqualityFn equalityFn]); -typedef _SelectorFnHook = TValue Function( +typedef _SelectorFnHook = TValue/*!*/ Function( TValue Function(TReduxState state) selector, [ bool Function(TValue tNextValue, TValue tPrevValue) equalityFn, ]); diff --git a/lib/src/over_react_redux/over_react_redux.dart b/lib/src/over_react_redux/over_react_redux.dart index 1070d5871..4860d3eed 100644 --- a/lib/src/over_react_redux/over_react_redux.dart +++ b/lib/src/over_react_redux/over_react_redux.dart @@ -155,21 +155,21 @@ typedef dynamic Dispatcher(dynamic action); /// /// For more info see: https://react-redux.js.org/api/connect#connect UiFactory Function(UiFactory) connect({ - Map Function(TReduxState state) mapStateToProps, - Map Function(TReduxState state, TProps ownProps) mapStateToPropsWithOwnProps, - Map Function(TReduxState state) Function(TReduxState initialState, TProps initialOwnProps) makeMapStateToProps, - Map Function(TReduxState state, TProps ownProps) Function(TReduxState initialState, TProps initialOwnProps) makeMapStateToPropsWithOwnProps, + Map Function(TReduxState/*!*/ state) mapStateToProps, + Map Function(TReduxState/*!*/ state, TProps ownProps) mapStateToPropsWithOwnProps, + Map Function(TReduxState/*!*/ state) Function(TReduxState/*!*/ initialState, TProps initialOwnProps) makeMapStateToProps, + Map Function(TReduxState/*!*/ state, TProps ownProps) Function(TReduxState/*!*/ initialState, TProps initialOwnProps) makeMapStateToPropsWithOwnProps, Map Function(Dispatcher dispatch) mapDispatchToProps, Map Function(Dispatcher dispatch, TProps ownProps) mapDispatchToPropsWithOwnProps, Map Function(Dispatcher dispatch) Function(Dispatcher dispatch, TProps ownProps) makeMapDispatchToProps, Map Function(Dispatcher dispatch, TProps ownProps) Function(Dispatcher dispatch, TProps ownProps) makeMapDispatchToPropsWithOwnProps, Map Function(TProps stateProps, TProps dispatchProps, TProps ownProps) mergeProps, - bool Function(TReduxState nextState, TReduxState prevState) areStatesEqual, + bool Function(TReduxState/*!*/ nextState, TReduxState/*!*/ prevState) areStatesEqual, // Use default parameter values instead of ??= in the function body to allow consumers // to specify `null` and fall back to the JS default. - bool Function(TProps nextProps, TProps prevProps) areOwnPropsEqual = propsOrStateMapsEqual, - bool Function(TProps nextProps, TProps prevProps) areStatePropsEqual = propsOrStateMapsEqual, - bool Function(TProps nextProps, TProps prevProps) areMergedPropsEqual = propsOrStateMapsEqual, + bool Function(TProps nextProps, TProps prevProps)/*?*/ areOwnPropsEqual = propsOrStateMapsEqual, + bool Function(TProps nextProps, TProps prevProps)/*?*/ areStatePropsEqual = propsOrStateMapsEqual, + bool Function(TProps nextProps, TProps prevProps)/*?*/ areMergedPropsEqual = propsOrStateMapsEqual, Context context, bool pure = true, bool forwardRef = false, @@ -203,7 +203,7 @@ UiFactory Function(UiFactory) connect Function(UiFactory) connect Function(UiFactory) connect Function(UiFactory) connect Function(UiFactory) connect - areStatesEqual(unwrapInteropValue(jsNext), unwrapInteropValue(jsPrev)); + areStatesEqual(unwrapInteropValue(jsNext) as TReduxState, unwrapInteropValue(jsPrev) as TReduxState); bool handleAreOwnPropsEqual(JsMap jsNext, JsMap jsPrev) => areOwnPropsEqual(jsPropsToTProps(jsNext), jsPropsToTProps(jsPrev)); @@ -396,7 +396,7 @@ UiFactory Function(UiFactory) connect(ReactInteropValue value) { - return value.value as T; +// TODO null-safety note: I removed the cast here so the null-safety tool could infer things better +dynamic unwrapInteropValue(ReactInteropValue value) { + return value.value; } /// A helper function that wraps a [value] in a [ReactInteropValue]. diff --git a/lib/src/util/css_value_util.dart b/lib/src/util/css_value_util.dart index e1e4312d5..7b539188e 100644 --- a/lib/src/util/css_value_util.dart +++ b/lib/src/util/css_value_util.dart @@ -22,12 +22,12 @@ class CssValue implements Comparable { /// The number component of this CSS value. /// /// E.g., 1 for '1px' - final num number; + final num/*!*/ number; /// The unit component of this CSS value. /// /// E.g., 'px' for '1px' - final String unit; + final String/*!*/ unit; /// Creates a new [CssValue]. /// @@ -51,6 +51,7 @@ class CssValue implements Comparable { /// 20 /// '1.25em' /// '-15%' + // FIXME null-safety this needs some manual migration after the tool factory CssValue.parse(dynamic source, {CssValue Function(dynamic value, dynamic error) onError}) { num number; String unit; diff --git a/lib/src/util/map_util.dart b/lib/src/util/map_util.dart index b3ea2c1be..3a4e1af8f 100644 --- a/lib/src/util/map_util.dart +++ b/lib/src/util/map_util.dart @@ -80,11 +80,11 @@ Map getPropsToForward(Map props, { /// DEPRECATED: Use [forwardUnconsumedPropsV2] instead. @Deprecated('This implementation does not filter DOM props correctly. Use forwardUnconsumedPropsV2 instead.') void forwardUnconsumedProps(Map props, { - bool omitReactProps = true, - bool onlyCopyDomProps = false, + bool/*!*/ omitReactProps = true, + bool/*!*/ onlyCopyDomProps = false, Iterable keysToOmit, Iterable keySetsToOmit, - Map propsToUpdate, + Map/*!*/ propsToUpdate, }) { if (onlyCopyDomProps) { for (final key in props.keys) { @@ -136,11 +136,11 @@ void forwardUnconsumedProps(Map props, { /// Identical to [forwardUnconsumedProps], with the exception of properly filtering /// DOM props. void forwardUnconsumedPropsV2(Map props, { - bool omitReactProps = true, - bool onlyCopyDomProps = false, + bool/*!*/ omitReactProps = true, + bool/*!*/ onlyCopyDomProps = false, Iterable keysToOmit, Iterable keySetsToOmit, - Map propsToUpdate, + Map/*!*/ propsToUpdate, }) { for (final key in props.keys) { if (keysToOmit != null && keysToOmit.contains(key)) continue; @@ -192,7 +192,7 @@ Map newStyleFromProps(Map props) { /// Returns the underlying map object of either [UiProps] or [UiState]. /// /// Used to take a typed factory object and get the underlying backing map. -Map getBackingMap(Map map) { +Map/*!*/ getBackingMap(Map/*!*/ map) { if (map is JsBackedMap) return map; if (map is component_base.UiProps) return getBackingMap(map.props); if (map is component_base.UiState) return getBackingMap(map.state); diff --git a/lib/src/util/react_wrappers.dart b/lib/src/util/react_wrappers.dart index 4c57e3132..d9e7c6e03 100644 --- a/lib/src/util/react_wrappers.dart +++ b/lib/src/util/react_wrappers.dart @@ -158,7 +158,7 @@ Map getProps(/* ReactElement|ReactComponent */ instance, {bool traverseWrappers if (cachedView != null) return cachedView; } - Map rawPropsOrCopy; + Map/*!*/ rawPropsOrCopy; final dartComponentVersion = _getDartComponentVersionFromInstance(instance); if (dartComponentVersion == ReactDartComponentVersion.component) { // ignore: invalid_use_of_protected_member From 80571810ad05e2794d483c95aa107f11e2ce461f Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Fri, 28 May 2021 12:57:48 -0700 Subject: [PATCH 012/211] More migration hints in core lib/src/component files --- lib/src/component/dom_components.dart | 412 +++++++++++++------------- lib/src/component/hooks.dart | 2 + lib/src/component/prop_mixins.dart | 1 + lib/src/component/resize_sensor.dart | 1 + 4 files changed, 210 insertions(+), 206 deletions(-) diff --git a/lib/src/component/dom_components.dart b/lib/src/component/dom_components.dart index 1296fcca0..5757a354e 100644 --- a/lib/src/component/dom_components.dart +++ b/lib/src/component/dom_components.dart @@ -85,826 +85,826 @@ abstract class Dom { /// Returns a new builder that renders an `` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps a([Map backingMap]) => DomProps(react.a as ReactComponentFactoryProxy, backingMap); + static DomProps a([Map backingMap]) => DomProps(react.a as ReactComponentFactoryProxy/*!*/, backingMap); /// Returns a new builder that renders an `` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps abbr([Map backingMap]) => DomProps(react.abbr as ReactComponentFactoryProxy, backingMap); + static DomProps abbr([Map backingMap]) => DomProps(react.abbr as ReactComponentFactoryProxy/*!*/, backingMap); /// Returns a new builder that renders an `
` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps address([Map backingMap]) => DomProps(react.address as ReactComponentFactoryProxy, backingMap); + static DomProps address([Map backingMap]) => DomProps(react.address as ReactComponentFactoryProxy/*!*/, backingMap); /// Returns a new builder that renders an `` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps area([Map backingMap]) => DomProps(react.area as ReactComponentFactoryProxy, backingMap); + static DomProps area([Map backingMap]) => DomProps(react.area as ReactComponentFactoryProxy/*!*/, backingMap); /// Returns a new builder that renders an `
` tag with getters/setters for all DOM-related React props, /// optionally backed by a specified map. - static DomProps article([Map backingMap]) => DomProps(react.article as ReactComponentFactoryProxy, backingMap); + static DomProps article([Map backingMap]) => DomProps(react.article as ReactComponentFactoryProxy/*!*/, backingMap); /// Returns a new builder that renders an `