Skip to content

migrate foundation to nullsafety #61188

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

Merged
merged 2 commits into from
Jul 15, 2020
Merged

migrate foundation to nullsafety #61188

merged 2 commits into from
Jul 15, 2020

Conversation

a14n
Copy link
Contributor

@a14n a14n commented Jul 9, 2020

Description

NNBD migration for foundation

Related Issues

Tests

I added the following tests:

None

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

@fluttergithubbot
Copy link
Contributor

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label Jul 9, 2020
@a14n a14n force-pushed the nnbd-foundation branch from 3697ae0 to 5f06144 Compare July 10, 2020 07:45
@a14n a14n force-pushed the nnbd-foundation branch 3 times, most recently from 1416458 to 12c3513 Compare July 10, 2020 09:30
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8
// @dart = 2.9
Copy link
Contributor

Choose a reason for hiding this comment

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

I think probably how this should be landed is by bumping the min sdk version in the pubspec to be a 2.9 release, and removing the // @Dart comments in the opted in files entirely. @jakemac53 @jonahwilliams does that sound right?

Copy link
Contributor

Choose a reason for hiding this comment

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

That sounds like an approach with less churn. Is 2.9 the null safety language version, or could that change?

Copy link
Contributor

Choose a reason for hiding this comment

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

2.9 will not be the final null safety language version. It is likely, but not guaranteed that 2.10 will be the final null safety language version.

Copy link
Contributor

Choose a reason for hiding this comment

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

okay, in that case we should definitely do it in the pubspec so there is only a single location, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefered to explicitly use // @dart = 2.9 during the incremental migration for simple searchability. Once all framework is migrated I will remove it. Note that the pubspec.yaml sdk version is already pointing to 2.9.

Does it look good to you?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, works for me. Note that if/when the Dart version bumps to a 2.10 pre-release, there will a bit of a bump - you won't be able roll 2.10 in until you change all of these from // @Dart = 2.9 to // @Dart = 2.10.

Copy link
Contributor

Choose a reason for hiding this comment

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

could we set it to 2.10 now?

Copy link
Contributor

Choose a reason for hiding this comment

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

could we set it to 2.10 now?

You could try it, but I wouldn't really recommend it. You're more or less relying on undefined behavior in that case. It might just work, in which case it's probably fine, but it also might work in some places and not others, or suddenly stop working, or whatever.

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is really just about tracking which things are migrated, maybe consider just using some other arbitrary string to tag them? // @Dart = migrated ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I'll remove it directly. I don't use it too much now.

@a14n a14n force-pushed the nnbd-foundation branch 2 times, most recently from 99a4718 to f032430 Compare July 13, 2020 15:21
@@ -5,3 +5,7 @@ include: ../analysis_options.yaml
analyzer:
enable-experiment:
- non-nullable
errors:
always_require_non_null_named_parameters: false # not needed with nnbd
void_checks: false # issues with nnbd
Copy link
Member

Choose a reason for hiding this comment

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

Is there an issue on file that we could link from here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

link to issue added.

errors:
always_require_non_null_named_parameters: false # not needed with nnbd
void_checks: false # issues with nnbd
unnecessary_null_comparison: false
Copy link
Member

Choose a reason for hiding this comment

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

Why do we turn this one off?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is needed to avoid warning on null assertion on non-nullable variable. For instance:

void m(String s) {
  assert(s != null);
}

This could change with #61042

Copy link
Member

Choose a reason for hiding this comment

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

If the variable itself is already non-nullable, why do we still need the assert? Wouldn't we want to clean that up and remove it?

Copy link
Member

Choose a reason for hiding this comment

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

Either way, It would probably be good to have a comment on this line explaining why we turn this off.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the variable itself is already non-nullable, why do we still need the assert?

See dart-lang/language#1018:

At first glance, it might seem sensible to remove the assertion on the grounds that c can no longer be null, but that's only true in strong mode. Flutter will have a long tail of users running in weak mode until Dart 3.0, and assertions like these are necessary to help prevent them from passing nulls to Flutter APIs.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the context and adding it as a comment.

assert(() {
optimizedValue = object.runtimeType.toString();
return true;
}());
return optimizedValue;
}

/// Allows promotion of a variable to another type.
Copy link
Member

Choose a reason for hiding this comment

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

This feels like a strange thing to add to flutter's public API. Looks like it is only used in one file. Can we just add it as a private thing there? Or, instead of using promote, can you just do the following in the code:

num n = 42;
n = n as int;
n.isEven;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't remind the issue but @Hixie suggested to add this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Finally I removed this function for now.

@@ -29,7 +27,7 @@ import 'dart:collection';
class ObserverList<T> extends Iterable<T> {
final List<T> _list = <T>[];
bool _isDirty = false;
HashSet<T> _set;
late final HashSet<T> _set = HashSet<T>();
Copy link
Member

Choose a reason for hiding this comment

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

Why late?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIRC this will make the field lazy initialized.

Copy link
Contributor

@jakemac53 jakemac53 Jul 14, 2020

Choose a reason for hiding this comment

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

It won't do anything in this case (other than maybe make it slower to access). It allows you to (yourself) lazily initialize it but leave it as a non-nullable type.

Copy link
Member

@goderbauer goderbauer Jul 14, 2020

Choose a reason for hiding this comment

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

Sorry if this wasn't clear, but my question was meant as: "Why are we declaring this field as late? It seems unnecessary here."

Copy link
Contributor

Choose a reason for hiding this comment

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

It was lazy before - I think there was a misunderstanding around what late means. If assigning immediately it has no meaning @stereotype441 should we have a lint for this?

To restore the lazy behavior that existed before this would have to be a nullable field type, and you would have to restore the old logic.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jakemac53 that's not correct. late with an initializer means lazy.

Copy link
Member

Choose a reason for hiding this comment

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

Now I am confused. What is the difference between those two lines?

late final int foo = 1;
final int bar = 1;

Copy link
Contributor

Choose a reason for hiding this comment

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

Nothing, because you can't observe laziness with a value. But:

class A {
  late final int foo = (() {print("hello"); return 1;})();
  final int bar = (() {print("world"); return 1;})();
  A();
}
                            
                            
void main() {
  var a = A();
  print("says");
  a.foo;
}

outputs

world
says
hello

because a late variable with an initializer only evaluates its initializer on first use.

cc @munificent this is something we're going to have to explain carefully.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation!

int start = 0;
int startForLengthCalculations = 0;
bool addPrefix = false;
int index = prefix.length;
_WordWrapParseMode mode = _WordWrapParseMode.inSpace;
int lastWordStart;
int lastWordEnd;
// TODO(a14n): use `late int lastWordStart;`
Copy link
Member

Choose a reason for hiding this comment

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

What's currently stopping us to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

late is a little dangerous for public member. I'm not sure the TODO is still relevant. I'll check.

Copy link
Member

Choose a reason for hiding this comment

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

I am not sure I fully understand, lastWordStart seems to be private to this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

comment removed. I added it to remind me that a lint could be done to use late.

@a14n a14n force-pushed the nnbd-foundation branch from 450a7a0 to d3b3016 Compare July 15, 2020 08:41
@a14n a14n force-pushed the nnbd-foundation branch from d3b3016 to 8ad5ea0 Compare July 15, 2020 13:24
@jakemac53
Copy link
Contributor

Note that force pushing destroys all pr comment history so please avoid that :).

Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

LGTM

@a14n a14n merged commit 978a2e7 into flutter:master Jul 15, 2020
@a14n a14n deleted the nnbd-foundation branch July 15, 2020 16:55
@dnfield
Copy link
Contributor

dnfield commented Jul 15, 2020

Pragya007 pushed a commit to Pragya007/flutter that referenced this pull request Aug 11, 2020
* migrate foundation to nullsafety

* address review comments
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
* migrate foundation to nullsafety

* address review comments
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants