-
Notifications
You must be signed in to change notification settings - Fork 28.7k
Audit covariant
usage in tool
#114112
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
Audit covariant
usage in tool
#114112
Conversation
@@ -197,8 +196,7 @@ abstract class DesktopDevice extends Device { | |||
} | |||
|
|||
/// Builds the current project for this device, with the given options. | |||
Future<void> buildForDevice( | |||
ApplicationPackage package, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package
wasn't used in any of the subclass implementation, remove.
@@ -533,7 +532,7 @@ class IOSSimulator extends Device { | |||
|
|||
@override | |||
Future<bool> stopApp( | |||
ApplicationPackage app, { | |||
ApplicationPackage? app, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where the nullability mismatch caused the runtime test failure seen during the roll
Since covariant
has been removed from the base class signature, there was correctly an error when this wasn't nullable.
@@ -497,16 +510,6 @@ class FlutterDevice { | |||
); | |||
} | |||
|
|||
if (package == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rearranged this check to be above the 'Launching ${package!.displayName} '
call, which would crash.
@@ -366,7 +366,7 @@ class AndroidDevice extends Device { | |||
|
|||
@override | |||
Future<bool> isAppInstalled( | |||
AndroidApk app, { | |||
ApplicationPackage app, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so for this call, will we just be more permissive and allow any ApplicationPackage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the right solution to this is not to make Device:
abstract class Device<A extends ApplicationPackage> {
isAppInstalled(A app, ...) {}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a much better solution, but it also means every single usage of the base class Device
becomes Device<ApplicationPackage>
if we can't derive the implemented type, and we have hundreds of them.
info: Specify type annotations. (always_specify_types)
I gave up with about 400 more warnings to go:
e780f1d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you want me to do with this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me make one more pass, we can land as is
@@ -478,7 +478,7 @@ class AndroidDevice extends Device { | |||
|
|||
@override | |||
Future<bool> uninstallApp( | |||
AndroidApk app, { | |||
ApplicationPackage app, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not covariant AndroidApk here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because covariant AndroidApk
would turns off the static analysis for this type, so if the base class switched to ApplicationPackage?
say, the analyzer wouldn't complain and we'd be back where we started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, I forgot
@@ -519,7 +519,7 @@ class AndroidDevice extends Device { | |||
|
|||
@override | |||
Future<LaunchResult> startApp( | |||
AndroidApk package, { | |||
AndroidApk? package, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why allow null for Android app?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be nullable because the base class is nullable due to web. That's the bug this is fixing--covariant
was hiding that null could be passed in, which in some cases caused crashes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, that was a brain fart on my part
@@ -720,11 +720,11 @@ class AndroidDevice extends Device { | |||
|
|||
@override | |||
Future<bool> stopApp( | |||
AndroidApk? app, { | |||
ApplicationPackage? app, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not covariant AndroidApk?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Despite the passing |
Going to reopen this and hopefully get new google testing failures. |
Remove
covariant
where possible to avoid subtle null safety issue. Where it's still useful, remove from base class and pushcovariant
into overrides to by-default enforce nullability wherecovariant
isn't needed.See https://dart.dev/guides/language/sound-problems#the-covariant-keyword about how this suppresses the analyzer.
This will need a g3fix.
Note I left the
covariant
instartApp
. That one is really a mess since most subclasses do expect it to be non-null, but it is legitimately called as null in the web case. I guess we can leave that one for now until it causes issues...flutter/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
Lines 242 to 245 in 156c313
Fixes #114090
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.