Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FED-1569 Prepare for null safety: fix lints and implicit casts #366

Merged
merged 31 commits into from
Aug 22, 2023

Conversation

greglittlefield-wf
Copy link
Collaborator

@greglittlefield-wf greglittlefield-wf commented Aug 21, 2023

Motivation

A while back @aaronlademann-wf started a branch to update react-dart's to use workiva_analysis_options and updated lints, and clean things up.

I then based off that branch, made some adjustments, and enabled implicit casts to improve type safety and make things easier when migrating to null safety. I then used that as a base for a null safety branch.

As a result, all of the null safety changes are dependent on these unmerged lint and implicit cast changes.

To get this repo in a better state, and to enable the merge of null safety changes, let's land these lint and implicit cast changes.

Changes

The original commits also ended up getting pretty messy, with some larger commits and quite a few merge commits in between. The changes also were based on workiva_analysis_options v1 instead of v2.

So, I ended up redoing/rebasing most of these changes, splitting them up into very granular and easy-to-review commits, and rebasing the null safety branch on top of those. Shoutout to @aaronlademann-wf for your original work on this! ❤️

For review, I highly recommend reviewing the changes commit-by-commit since there are so many different lint fixes that touch a lot of code. There's a lot of commits, but most of them are either small or dart fix --apply ones that are very easy to review.

Summary of changes:

  • Upgrade lint configuration to workiva_analysis_options v2, and customize some lints
  • Fix lints
    • The vast majority of these are individual commits using dart fix --apply
  • Fix implicit casts
    • This was done primarily in one commit, along with related adjustments make variables final and remove LHS typing where possible
    • The vast majority of these changes occurred in example and test directories; changes to lib were minimal, so the risk of regression here should be pretty low so long as the lib changes are reviewed thoroughly.
    • I couldn't disable implicit casts an analysis_options since we'd still get a lot of warnings as a result of ReactComponentFactoryProxy.call returning dynamic as opposed to ReactElement. I'd like to change that typing, but since that's technically a major change, let's save that for another PR.
  • Stop running CI on Dart 3 until we're null-safe (it was failing on this PR)

Testing

greglittlefield-wf and others added 28 commits August 9, 2023 14:58
The fewer explicit types we have, the fewer need to be updated
during the transition to null safety

Done via replacement of `(@OverRide\n  )(?![gs]et )([^(=\n]+ )([^(=\n]+\()` with `$1/$3`
The fewer explicit types we have, the fewer need to be updated
during the transition to null safety

Done via replacement of `(@OverRide\n  )([^(=\n]+ )(get [^(=\n]+=)` with `$1/$3`
@aviary-wf
Copy link

Security Insights

No security relevant content was detected by automated scans.

Action Items

  • Review PR for security impact; comment "security review required" if needed or unsure
  • Verify aviary.yaml coverage of security relevant code

Questions or Comments? Reach out on Slack: #support-infosec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to review commits one-by-one!

This should make review much easier. See PR description for more info

@rmconsole6-wk rmconsole6-wk changed the title Prepare for null safety: fix lints and implicit casts FED-1569 Prepare for null safety: fix lints and implicit casts Aug 21, 2023
@greglittlefield-wf greglittlefield-wf marked this pull request as ready for review August 21, 2023 21:52
@greglittlefield-wf greglittlefield-wf requested review from a team, annawatson-wk and hunterbreathat-wk and removed request for a team, annawatson-wk and hunterbreathat-wk August 21, 2023 23:43
@aaronlademann-wf aaronlademann-wf self-assigned this Aug 22, 2023
Copy link
Collaborator

@aaronlademann-wf aaronlademann-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly some questions...

Other than that, I can plus one / ten this after that...

Comment on lines -2120 to -2124
/// Create React DOM `Component`s by calling the specified [creator].
_createDOMComponents(creator) {
a = creator('a');
abbr = creator('abbr');
address = creator('address');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long has this been hanging around unused?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 685 to +686
String get displayName {
var value;
String value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming there's no reason to worry about this type being tightened?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope; originally it was a dynamic variable that would always be either assigned to a String or uninitialized, then implicitly casted to a String when it was returned.

@@ -7,6 +7,7 @@ import 'dart:collection';
import 'dart:js_util';

import 'package:js/js.dart';
import 'package:react/react_client/react_interop.dart' show forwardRef2;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for posterity: this was added for a reference in a doc comment.

lib/src/react_client/dart_interop_statics.dart Outdated Show resolved Hide resolved
Comment on lines 104 to +105
children = shouldAlwaysBeList ? childrenArgs.map(listifyChildren).toList() : childrenArgs;
markChildrenValidated(children);
markChildrenValidated(children as List);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this still get cast as List if shouldAlwaysBeList is false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the line above, the value chlidren is reassigned to is always a List, and markChildrenValidated takes in a List, but the static type of children is still dynamic so we need a cast here.

In null safety, with Dart's type inference improvements, children actually has a static type of List, and this becomes an unnecessary cast warning and ends up getting removed.

Comment on lines +107 to +108
final files = List<File>.from(rawFiles ?? []);
final types = List<String>.from(rawTypes ?? []);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be

Suggested change
final files = List<File>.from(rawFiles ?? []);
final types = List<String>.from(rawTypes ?? []);
final files = List.from(rawFiles ?? []).cast<File>();
final types = List.from(rawTypes ?? []).cast<String>();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this case, either would be acceptable.

List<File>.from(rawFiles ?? []) creates a new list and casts objects to the target type as they're copied.

List.from(rawFiles ?? []).cast<File>() creates a new List<dynamic> and then returns a view on that list that casts items as they're accessed.

Casting them on copy feels better to me in this case, though, so that any bad typing is revealed always, when the event is dispatched, as opposed to only when these properties are accessed.

Copy link
Collaborator

@aaronlademann-wf aaronlademann-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@aaronlademann-wf
Copy link
Collaborator

QA +1

@Workiva/release-management-pp

Copy link
Collaborator

@sydneyjodon-wk sydneyjodon-wk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on Aaron's commit

Copy link

@rmconsole-wf rmconsole-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 from RM

@rmconsole7-wk rmconsole7-wk merged commit 5b4aef1 into master Aug 22, 2023
1 check passed
@rmconsole7-wk rmconsole7-wk deleted the lints-and-implicit-casts-take-2 branch August 22, 2023 18:57
@aaronlademann-wf aaronlademann-wf removed their assignment Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants