-
Notifications
You must be signed in to change notification settings - Fork 166
Lint for SizedBox.shrink(...)
and SizedBox.expand(...)
#3039
Lint for SizedBox.shrink(...)
and SizedBox.expand(...)
#3039
Conversation
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.
Looks like you're headed in the right direction. Hope you don't mind the early review.
@override | ||
void visitArgumentList(ArgumentList node) { | ||
for (var name in node.arguments | ||
.cast<NamedExpression>() |
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 isn't safe to assume that all of the arguments are named expressions. The lints are run over code that's invalid, so you'll need to handle the case where the user didn't provide a name (SizedBox(0, child: child)
).
You probably want to treat such cases as 'incompatible' parameters to keep the lint from firing on invalid code.
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.
done
This will have to be updated in the analyzer package (which has our mocked SDK). I'll tackle that but it may be a bit before a new analyzer is published. In the meantime, maybe you can get by with |
See: dart-archive/linter#3039 Change-Id: If0a2a02591a0a46c0c463ff2e79f35a1209dff35 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217700 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
Ok, with that work around it looks like I'm now getting to the point where the tests are failing due to the lint not being correctly implemented =) |
This comment has been minimized.
This comment has been minimized.
r'''Use SizedBox.shrink and SizedBox.expand constructors appropriately. | ||
|
||
The `SizedBox.shrink(...)` and `SizedBox.expand(...)` constructors should be used | ||
instead of the more general `SizedBox(...)` constructor for specific use cases. |
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.
Consider defining / describing the use cases for which this lint applies.
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.
Took a first swing, unsure how I feel about it tho
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.
Maybe something that suggests this is for readability purposes?
/fyi @goderbauer @Hixie who might have opinions.
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.
Maybe replace the generic "for specific use cases" with "to improve readability"?
This comment has been minimized.
This comment has been minimized.
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.
Sorry for the slow replies!
**Examples** | ||
|
||
**BAD:** | ||
``` |
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.
Consider adding the dart language tag to these code blocks.
=>
```dart
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.
done
Widget sizedBoxWithInfiniteWidthInfiniteHeight() { | ||
return SizedBox( | ||
// LINT | ||
height: double.INFINITY, |
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.
With @scheglov's updates to the mock SDK, I think you'll want to bump these to:
double.infinity
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.
With @scheglov's updates to the mock SDK, I think you'll want to bump these to:
double.infinity
Any idea when this will land? Or should I commit this file with a TODO?
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.
Should be already available in analyzer 2.7.0
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.
done
return SizedBox( | ||
// OK | ||
height: 0, | ||
width: double.INFINITY, |
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.
And 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.
done
Widget sizedBoxWithZeroWidthInfiniteHeight() { | ||
return SizedBox( | ||
// OK | ||
height: double.INFINITY, |
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.
And 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.
done
Widget sizedBoxWithInfiniteWidth() { | ||
return SizedBox( | ||
// OK | ||
width: double.INFINITY, |
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.
- ^
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.
done
Widget sizedBoxWithInfiniteHeight() { | ||
return SizedBox( | ||
// OK | ||
height: double.INFINITY, |
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.
- ^
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.
done
r'''Use SizedBox.shrink and SizedBox.expand constructors appropriately. | ||
|
||
The `SizedBox.shrink(...)` and `SizedBox.expand(...)` constructors should be used | ||
instead of the more general `SizedBox(...)` constructor for specific use cases. |
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.
Maybe something that suggests this is for readability purposes?
/fyi @goderbauer @Hixie who might have opinions.
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's a little hard to follow the conversation at this point. Are you still seeing test failures?
(argument.propertyName.name == 'infinity' || | ||
argument.propertyName.name == 'INFINITY')) { | ||
var target = argument.target; | ||
if (target is SimpleIdentifier && target.name == 'double') { |
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's a corner case that will probably never come up, and a bug that came from me, but if a user imports dart:core
using a prefix, then the target
will be a PrefixedIdentifier
. If you care about catching this case you can add an else if
for it.
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.
Added a condition to the if for PrefixedIdentifier
version of double
.
|
||
Widget sizedBoxWithZeroWidthZeroHeight() { | ||
return SizedBox( | ||
// LINT |
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 believe that the 'LINT' marker needs to be on the same line as that on which the lint will be reported. The lint is currently (correctly IMO) reported on the name of the class on line 11, so I think this marker needs to be moved onto line 11. Similarly below. This probably isn't what's causing the current test failure, but I suspect it will cause a different form of test failure after the current failure is fixed.
The 'OK' markers won't cause that problem, but should probably be moved up to the preceding line for consistency.
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.
The issue is that the dart format tooling is automatically moving the // LINT
comment to the next line. I'll edit it with vi
=)
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.
Even with this change, I'm still seeing a failure.
$ dart test -N sized_box_shrink_expand
00:05 +0: test/rule_test.dart: rule dart sized_box_shrink_expand
/Users/brettmorgan/Documents/GitHub/linter/test_data/rules/sized_box_shrink_expand.dart 11:10 [lint] Use the `SizedBox.shrink` constructor.
return SizedBox( // LINT
^^^^^^^^
null files analyzed, 1 issue found, in null ms.
00:05 +0 -1: test/rule_test.dart: rule dart sized_box_shrink_expand [E]
Expected: matches [Annotation:<[LINT]: "null" (line: 11) - [null:null]>, Annotation:<[LINT]: "null" (line: 19) - [null:null]>] unordered
Actual: [
Annotation:[LINT]: "Use the `SizedBox.shrink` constructor." (line: 11) - [10:8]
]
Which: has too few elements (1 < 2)
package:test_api expect
test/rule_test.dart 254:7 testRule.<fn>
00:05 +0 -1: loading test/rule_test.dart
Consider enabling the flag chain-stack-traces to receive more detailed exceptions.
For example, 'dart test --chain-stack-traces'.
00:05 +0 -1: Some tests failed.
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 consider the formatter's behavior to be a bug, so I opened dart-lang/dart_style#1070.
But I'm not surprised that it's still failing. I mentioned the placement of the comments because I suspect that the test code first verifies that the correct number of lints were produced, and then verifies that each of the lints was in the expected location. With the markers in the wrong places, fixing the number of lints would cause the second failure to occur.
It appears that the missing lint is the one on line 19 (the double.infinity
case). I don't see any obvious reason when I look at the code, though my guess would be that the bug is in the code that's computing the value of the argument. I'd try setting a breakpoint in that method (after commenting out all the other cases so there's less noise) and debugging the lint.
Tests are green now |
Now that I kinda understand how lints work, I'm curious how I can add |
The doc https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/doc/tutorial/quick_fix.md should have most of the information you need. Please let me know if there's information that you would have found useful that's missing from the current state of the doc. |
SizedBox.shrink(...)
and SizedBox.expand(...)
SizedBox.shrink(...)
and SizedBox.expand(...)
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! Unless @bwilkerson had any unresolved concerns?
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.
Happy to see it land as is.
positionalArgumentFound = true; | ||
return; | ||
} | ||
if (argument.name.label.name == 'width') { |
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.
The code is fine as is, but I'll point out that there's a lot of repetition of argument.name.label.name
, so it might be a little cleaner to assign it to a local variable (here and below).
Thanks all for the thoughtful back and forth. So great to see this land! 🦅 |
…ive/linter#3039) * Start of a lint for `SizedBox.shrink(...)` and `SizedBox.expand(...)` * Copyright year * Add test cases * double.infinity -> double.INFINITY * next step * next step * Add single backquotes to diagnostic messages * Add description * use static LintCodes * tidyup * Check for positional arguments * Define use case for SizedBox.shrink and SizedBox.expand * Drop the SimpleAstVisitor * Dart language tags and backticks * Add in PrefixedIdentifier for double * Move `// LINT` comment to the right line * double.INFINITY -> double.infinity * Updated to reflect reality * Introduce local var for argument.name.label
Hey @pq,
This is the start of a lint for
SizedBox.shrink(...)
andSizedBox.expand(...)
. When finished, this will fix dart-lang/sdk#58152. I'm using #2049 as the starting point.However, I'm hitting an issue with
double.infinity
and I can't see how to patch it into the mock_packages.Halp?