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

Wrap with column missing in flutter IDEs #2492

Closed
ryaninja opened this issue May 25, 2020 · 14 comments
Closed

Wrap with column missing in flutter IDEs #2492

ryaninja opened this issue May 25, 2020 · 14 comments
Labels
in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug
Milestone

Comments

@ryaninja
Copy link

I've tried this in both Android Studio and VSCode, but the context menu to wrap in column simply doesn't appear for me. I'm trying to follow a layout tutorial, but I get this error at pretty much the first hurdle. Has this feature been removed/replaced? Anyone got any ideas?

Here's what the guide looks like:
https://i.stack.imgur.com/fpKV2.jpg

And here's what I see:
https://i.stack.imgur.com/yZu5M.jpg

@ryaninja
Copy link
Author

Ok, so it turns out you need to right-click and not highlight the widget and then right click. Wrap in column showed as soon as I did this.

@DanTup
Copy link
Member

DanTup commented May 25, 2020

@bwilkerson @scheglov does this seem like a bug? When invoking the assist menu one character from the end of a widget class, Wrap in Row/Column show up. However if the cursor is after the last character, they do not (however the others do). I can't think of a reason for this (nor can I see an obvious reason from the code why this happens):

Screenshot 2020-05-25 at 15 40 43

Screenshot 2020-05-25 at 15 40 51

@bwilkerson
Copy link

I can't think of any valid reason for the behavior being different between these two selection locations, so I'd consider this to be a bug.

Note that "Wrap with Row" is also missing. Both it and "Wrap with Column" are implemented in a single method. That method uses SelectionAnalyzer to convert a selection range to a set of AST nodes, and my guess (though I haven't dug into it enough to know for sure) is that that class selects an AST node that the method in question doesn't handle correctly, and that that's the source of the bug.

@DanTup
Copy link
Member

DanTup commented May 26, 2020

Ok, took a quick look at this. When the cursor is inside the name of the widget, analyzer.coveringNode from the SelectionAnalzyer correctly identifies the widget expression. However, when it's like this:

WidgetFoo^('test')

The selection analyzer picks up the argument list ('test') as the innermost covering node (since it starts at that offset), and flutter.identifyWidgetExpression exits early (without walking up parents) when it finds argument lists:

https://github.com/dart-lang/sdk/blob/93313eb2449099e20ade80d4760f76a325a4e176/pkg/analysis_server/lib/src/utilities/flutter.dart#L325-L327

Removing node is ArgumentList from that condition causes this case to work, however it breaks some other tests (for example test_identifyWidgetExpression_node_instanceCreation which is explicitly checking for this behaviour).

I'm not sure what a good fix is. If feels like the cursor being to the left of a paren in an argument list maybe should not be treated as being in the argument list, but that also feels like a weird exception.

@DanTup DanTup reopened this May 26, 2020
@DanTup DanTup added this to the v3.12.0 milestone May 26, 2020
@bwilkerson
Copy link

A possible short-term work around would be to check in the assists to see whether the covering node is an argument list whose parent is a widget expression. If we add a comment explaining why we're doing it, then we'd have some context in case we decide to change SelectionAnalyzer in the future.

@scheglov I'm interested in your thoughts on this.

@DanTup
Copy link
Member

DanTup commented Jun 11, 2020

@scheglov do you have any additional thoughts on this? If not, I might have a go at doing what @bwilkerson suggested above. Thanks!

@bwilkerson
Copy link

A note on implementation.

In order to better support being able to apply multiple fixes simultaneously, we changed the way we're implementing both fixes and assists. They now use instances of a subclass of CorrectionProducer to build the actual edits. The fixes have all been converted at this point, but most of the assists have not been.

Prior to these changes, fixes and assists each had a slightly different way of computing the node used as the starting point for creating the edits. Usually they produced the same node, but in a few cases they differed. In the new architecture they are consistent. That has meant that sometimes when converting a fix or assist we've had to update the code slightly to adjust for the change in starting node.

So, if you're interested in looking into this, it would be good if you first converted the existing assist to use the CorrectionProducer pattern. It's possible that doing so would impact the way the bug needs to be fixed, and it would be nice not to have to do the conversion after the fix is applied. That said, I won't say to no to getting the bug fixed without the extra work!

@scheglov
Copy link

It is mostly a matter of covering reasonable cases.
It is reasonable to propose Wrap in this case Widget^(...).
But we might have to do differently for Widget(..., child^).

@DanTup DanTup modified the milestones: v3.12.0, On Deck Jun 22, 2020
@DanTup
Copy link
Member

DanTup commented Jun 25, 2020

So, if you're interested in looking into this, it would be good if you first converted the existing assist to use the CorrectionProducer pattern.

Looks like you beat me to this :-)

It is reasonable to propose Wrap in this case Widget^(...).
But we might have to do differently for Widget(..., child^).

I think we could specifically handle the case where the caret is at exactly the offset of the argument list (eg. the caret is to the left of the open paren) - coveringNode is ArgumentList && coveringNode.offset == selectionOffset? I've opened a change that does that here:

https://dart-review.googlesource.com/c/sdk/+/152521/

@DanTup DanTup modified the milestones: On Deck, v3.13.0 Jun 25, 2020
@bwilkerson
Copy link

lgtm

dart-bot pushed a commit to dart-lang/sdk that referenced this issue Jun 25, 2020
…nt list

Bug: Dart-Code/Dart-Code#2492
Change-Id: I296f9396b3eedcbd1a63f272ed34c65f9d95d83b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152521
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Danny Tuppeny <danny@tuppeny.com>
@DanTup DanTup closed this as completed Jun 29, 2020
@DanTup DanTup removed this from the v3.13.0 milestone Jul 28, 2020
@mich040m
Copy link

Still happening as described here

@bwilkerson @scheglov does this seem like a bug? When invoking the assist menu one character from the end of a widget class, Wrap in Row/Column show up. However if the cursor is after the last character, they do not (however the others do). I can't think of a reason for this (nor can I see an obvious reason from the code why this happens):

Screenshot 2020-05-25 at 15 40 43 Screenshot 2020-05-25 at 15 40 51

@bwilkerson
Copy link

Yes, that looks like a bug. The question is: does the version of the Flutter SDK that you're using include the fix. It sometimes takes a long time for a fix to make it into a build. Unfortunately, I can't remember how to determine that information, even if I knew which version of the Flutter SDK you're using.

@DanTup
Copy link
Member

DanTup commented Feb 24, 2022

I can reproduce this, but it's slightly different to the original report/fix - in that case the cursor was at the end of ModelBinding (the highlight is just VS code highlighting the references) and that works. However if you select the widget name, Wrap with Column is still missing.

# present
"range":{"start":{"line":54,"character":11},"end":{"line":54,"character":11}}
# present
"range":{"start":{"line":54,"character":23},"end":{"line":54,"character":23}}
# missing
"range":{"start":{"line":54,"character":11},"end":{"line":54,"character":23}}

@DanTup DanTup reopened this Feb 24, 2022
@DanTup DanTup added this to the v3.36.0 milestone Feb 24, 2022
@DanTup DanTup added in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug and removed fixed in dart / flutter labels Feb 24, 2022
copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Feb 24, 2022
…or names selected

Fixes Dart-Code/Dart-Code#2492.

Change-Id: I5347e3ade842c3a155809e5224ca0ab40dd8651b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/234285
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
@DanTup
Copy link
Member

DanTup commented Feb 24, 2022

With dart-lang/sdk@8480657, these actions will also work if the whole widget name is selected. The fix is in the SDK so will ship with a future Flutter SDK release (rather than the Dart extension for VS Code).

@DanTup DanTup closed this as completed Feb 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug
Projects
None yet
Development

No branches or pull requests

5 participants