Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Lint for SizedBox.shrink(...) and SizedBox.expand(...) #3039

Merged
merged 21 commits into from
Nov 2, 2021
Merged

Lint for SizedBox.shrink(...) and SizedBox.expand(...) #3039

merged 21 commits into from
Nov 2, 2021

Conversation

domesticmouse
Copy link
Contributor

Hey @pq,

This is the start of a lint for SizedBox.shrink(...) and SizedBox.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.

$ dart test -N sized_box_shrink_expand
00:03 +0 -1: test/rule_test.dart: rule dart sized_box_shrink_expand [E]                                                                                                        
  Unexpected diagnostics:
  
  test_data/rules/sized_box_shrink_expand.dart 55:20 The getter 'infinity' isn't defined for the type 'double'.
  test_data/rules/sized_box_shrink_expand.dart 23:19 The getter 'infinity' isn't defined for the type 'double'.
  test_data/rules/sized_box_shrink_expand.dart 39:19 The getter 'infinity' isn't defined for the type 'double'.
  test_data/rules/sized_box_shrink_expand.dart 22:20 The getter 'infinity' isn't defined for the type 'double'.
  package:test_api           fail
  test/rule_test.dart 249:7  testRule.<fn>
  
00:03 +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'.

Halp?

@domesticmouse domesticmouse marked this pull request as draft October 21, 2021 06:01
@google-cla google-cla bot added the cla: yes label Oct 21, 2021
@coveralls
Copy link

coveralls commented Oct 21, 2021

Coverage Status

Coverage decreased (-0.009%) to 94.149% when pulling bd4a9d4 on domesticmouse:sized_box_shrink_expand into 7058a80 on dart-lang:master.

Copy link
Contributor

@bwilkerson bwilkerson left a 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>()
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@pq
Copy link
Contributor

pq commented Oct 21, 2021

However, I'm hitting an issue with double.infinity and I can't see how to patch it into the mock_packages.

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 double.INFINITY? (That does seem to be there.)

copybara-service bot pushed a commit to dart-lang/sdk that referenced this pull request Oct 22, 2021
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]>
@domesticmouse
Copy link
Contributor Author

In the meantime, maybe you can get by with double.INFINITY? (That does seem to be there.)

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 =)

@domesticmouse

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.
Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor

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"?

@domesticmouse

This comment has been minimized.

Copy link
Contributor

@pq pq left a 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:**
```
Copy link
Contributor

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

Copy link
Contributor Author

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,
Copy link
Contributor

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

Copy link
Contributor Author

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?

Copy link
Contributor

@scheglov scheglov Oct 27, 2021

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

Copy link
Contributor Author

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,
Copy link
Contributor

Choose a reason for hiding this comment

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

And 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.

done

Widget sizedBoxWithZeroWidthInfiniteHeight() {
return SizedBox(
// OK
height: double.INFINITY,
Copy link
Contributor

Choose a reason for hiding this comment

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

And 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.

done

Widget sizedBoxWithInfiniteWidth() {
return SizedBox(
// OK
width: double.INFINITY,
Copy link
Contributor

Choose a reason for hiding this comment

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

  • ^

Copy link
Contributor Author

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,
Copy link
Contributor

Choose a reason for hiding this comment

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

  • ^

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor

@bwilkerson bwilkerson left a 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') {
Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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.

Copy link
Contributor Author

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 =)

Copy link
Contributor Author

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.                                                                                                  

Copy link
Contributor

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.

@domesticmouse domesticmouse marked this pull request as ready for review October 28, 2021 03:55
@domesticmouse
Copy link
Contributor Author

It's a little hard to follow the conversation at this point. Are you still seeing test failures?

Tests are green now

@domesticmouse
Copy link
Contributor Author

Now that I kinda understand how lints work, I'm curious how I can add dart fix fixes for these two lints?

@bwilkerson
Copy link
Contributor

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.

@domesticmouse domesticmouse changed the title Start of a lint for SizedBox.shrink(...) and SizedBox.expand(...) Lint for SizedBox.shrink(...) and SizedBox.expand(...) Nov 1, 2021
Copy link
Contributor

@pq pq left a 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?

Copy link
Contributor

@bwilkerson bwilkerson left a 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') {
Copy link
Contributor

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).

@pq
Copy link
Contributor

pq commented Nov 2, 2021

Thanks all for the thoughtful back and forth. So great to see this land!

🦅

@pq pq merged commit 2e1800e into dart-archive:master Nov 2, 2021
@domesticmouse domesticmouse deleted the sized_box_shrink_expand branch November 3, 2021 11:07
copybara-service bot pushed a commit to dart-lang/sdk that referenced this pull request Aug 23, 2023
…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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

Successfully merging this pull request may close these issues.

Use SizedBox.shrink(...) and SizedBox.expand(...) constructors appropriately
6 participants