8000 add "destructure variable declaration" assist(s) · Issue #52025 · dart-lang/sdk · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

add "destructure variable declaration" assist(s) #52025

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

Open
pq opened this issue Apr 12, 2023 · 7 comments
Open

add "destructure variable declaration" assist(s) #52025

pq opened this issue Apr 12, 2023 · 7 comments
Labels
area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. devexp-assist Issues with analysis server assists P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@pq
Copy link
Member
pq commented Apr 12, 2023

Particularly for records, a destructuring assist would be handy and I expect commonly used but it would be interesting to explore lists, maps and objects too.

Records

For example,

(int, int) f() => (0,1);

m() {
  var r = f();
}

could become

(int, int) f() => (0,1);

m() {
  var (f1, f2) =  f();
}

And,

point() => (x: 1, y: 2);

z() {
  var r = point();
}

might become:

point() => (x: 1, y: 2);

z() {
  var (:x, :y) = point();
}

It gets interesting if the record declaration is accessed.

For example, I'd expect no assist in this case:

(int, int) f() => (0,1);

m() {
  var r = f();
  print(r);
}

but,

(int, int) f() => (0,1);

m() {
  var r = f();
  print(r.$1);
  print(r.$2);
}

could reasonably become:

(int, int) f() => (0,1);

m() {
  var (f1, f2) = f();
  print(f1);
  print(f2);
}

Maps

Map<String,int>  f() => {'x': 1};

m() {
  var r = f();
}

could become

Map<String,int>  f() => {'x': 1};

m() {
  var {} =  f();
}

(But note, they'll need to do something to {} since map patterns can't be empty.)

Lists

List<int> f() => [];

m() {
  var r = f();
}

could become

List<int> f() => [];

m() {
  var [] = f();
}

(Or var [...] = f();)

Objects

In a simple case we might take something like

class A {
  int a;
  A(this.a);
}

f() => A(1);

m() {
  var o = f();
}

to:

class A {
  int a;
  A(this.a);
}

f() => A(1);

m() {
  var A(:a) = f();
}

but this doesn't scale if A has a lot of fields.

Maybe better to start w/

var A() = f();

and possibly go better if fields are accessed.

class A {
  int a, b, c;
  A(this.a, this.b, this.c);
}

f() => A(1, 2, 3);

m() {
  var o = f();
  print('${o.a} ${o.b}');
}

could become

class A {
  int a, b, c;
  A(this.a, this.b, this.c);
}

f() => A(1, 2, 3);

m() {
  var A(:a, :b) = f();
  print('$a $b');
}
@pq pq added legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on devexp-assist Issues with analysis server assists labels Apr 12, 2023
@pq pq self-assigned this Apr 12, 2023
@bwilkerson
Copy link
Member

I'm not convinced that the non-record cases carry their weight, but I do agree that an assist to destructure a record is worth considering. If we add this, we should focus on records for a first cut and then consider the others as enhancements to the base functionality.

@pq
Copy link
Member Author
pq commented Apr 13, 2023

/fyi @leafpetersen

copybara-service bot pushed a commit that referenced this issue Apr 14, 2023
First, basic cut.

See: #52025

Change-Id: I3388f5ec96a45211669e3ac8a5975ff39feea4bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295381
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
@pq
Copy link
Member Author
pq commented Apr 14, 2023

Basic records support landed w/ cae0bfa.

There's an open question of whether a field name suggestion should be a linked edit (https://dart-review.googlesource.com/c/sdk/+/295381/comment/6c626001_ad74fd62/) which I'll return to. Also, I wonder if we should add wildcards as additional suggestions for positional fields?

That is, we might add _ after $1 here:

image

@bwilkerson?

@bwilkerson
Copy link
Member

I like the idea of offering a wildcard pattern here, it's a reasonable choice.

We should also consider suggesting wildcard patterns in code completion.

@stereotype441
Copy link
Member

I like this idea, especially for record and object patterns. I'm not quite as convinced by the map and list use cases.

Is there a way that we could make it available even if there's no pre-existing variable declaration? I.e. if I have:

class A {
  int a;
  A(this.a);
}

f() => A(1);

m() {
  f();
}

it would be nice if I could put the cursor on the f(); statement and trigger an assist that changes it to var A(:a) = f();

@pq
Copy link
Member Author
pq commented Apr 17, 2023

Is there a way that we could make it available even if there's no pre-existing variable declaration?

Currently the expectation is that you'd do this in two steps, introducing the local variable first.

image

I do like the idea of supporting this in one go though. Maybe we could add something like "Assign value to a new destructured pattern variable" to the already existing assist?

(Word-smithing welcome.)

(FWIW @bwilkerson, @scheglov: this is another example of micro vs. macro edits as discussed earlier today.)

@pq pq added the dart-model-language-patterns Issues with analyzer's support for the patterns language feature label Apr 17, 2023
@pq
Copy link
Member Author
pq commented Apr 17, 2023

After some thinking and an informal poll of folks, I'd like to go ahead with a simple conversion for Object patterns that takes

class A {
  int a;
  A(this.a);
}

f() => A(1);

m() {
  var o = f();
}

and produces

class A {
  int a;
  A(this.a);
}

f() => A(1);

m() {
  var A() = f();
}

with the caret inside the new declaration (A( < caret > )) assuming that folks will use code completion to fill in the fields they care about. (Note that completion improvements are being tracked in: #52058.)

copybara-service bot pushed a commit that referenced this issue Apr 17, 2023
See: #52025

Change-Id: I298c7f5b82b47b8cb02ca1a401e0658aab8f40a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295680
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
copybara-service bot pushed a commit that referenced this issue Apr 18, 2023
See: #52025

Change-Id: I6dc5d2f0c8391d8ad719c23b47aadeac9a8ab969
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295722
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label Mar 18, 2024
@bwilkerson bwilkerson added area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. and removed legacy-area-analyzer Use area-devexp instead. labels Feb 21, 2025
@bwilkerson bwilkerson removed the dart-model-language-patterns Issues with analyzer's support for the patterns language feature label Mar 13, 2025
@pq pq removed their assignment Apr 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. devexp-assist Issues with analysis server assists P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants
0