dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.25k stars 1.58k forks source link

When defining a new, concrete subclass, analyzer could add required methods #25817

Open sethladd opened 8 years ago

sethladd commented 8 years ago

If I have this:

abstract class Foo {
  foo();
}

And then I type this:

class Bar extends Foo {

And then I hit enter, I'd love to see this:

class Bar extends Foo {
  @override
  foo() {
    // TODO: implement
  }
}

Without requiring me to run a Quick Fix to add missing methods.

Thanks!

bwilkerson commented 8 years ago

@devoncarew @jwren This would require support from the client and possibly from analysis server (unless you could just ask for quick fixes, recognize the "add missing methods" and run it).

devoncarew commented 8 years ago

Possibly another way of approaching this is to use code completion. So, when the user hasn't quite finished typing class Bar extends Fo^, one of the code completion options would be to complete Foo, insert a class template { ... }, and supply any abstract methods?

Or we could trigger on the insertion of the { char, check if the line matches a known pattern, and auto run the quick fix. That would be fairly straightforward. Instead of add missing methods, we might want something more specific, like create class body. That would create missing methods if there were any.

bwilkerson commented 8 years ago

Either of those suggestions works for me.

@danrubel What do you think about the code completion suggestion?

danrubel commented 8 years ago

Traditionally, code completion is on identifiers. If we want to complete on { or other non-alphanumeric characters, then we would need to updated multiple clients. Not impossible, but work.

I recommend adding a new code completion contributor that offers a template for class Bar extends Fo^ like @devoncarew suggested above.

jwren commented 8 years ago

I like the idea. I think it would demo great, but I also think it is a slippery slope- there are lots of opportunities like this, where we provide a quick fix.

Users and code completion UIs are setup to have short (and not multiple lines) of code to complete.

bwilkerson commented 8 years ago

I don't think there's a problem having both. The code completion is convenient when creating a new class, but we need the quick fix for the case where an existing subclass of an abstract class needs to be update because the superclass had new abstract methods added to it.

danrubel commented 8 years ago

I agree that it's a slippery slope and think that it should not, but don't feel strongly about it.

lukechurch commented 8 years ago

@jwren

I like the direction this is heading in. We could be a whole lot smarter about how we support the user with code inject, but we do also need to be careful not to be surprising or distracting and not breaking users' interaction when they're working quickly and so needing a highly predictable system.

I think the problem is more that the Quick Fixes are not fluid to use right now, I've never got into the habit of using them in Dart as I did in C#. I think that's mainly a detailed UI interaction issue.

E.g. Visual Studio code completion provides very local changes, but has a much better affordance than we do for advertising quick fixes (if I remember correctly it's a glyph that floats over the code can be hovered on to reveal a drop down of actions). This makes it very quick to advertise and consume a fix in context, and they're pretty careful to make sure that only relevant and high importance fixes are offered like this. IIRC they also have smarter edit models in them, so if you edit the name of a variable there's a quick fix that propagates that edit as a refactor again advertised via the same mechanism.

So in general it seems worth allowing ourselves to have three UI interaction modes:

Default on - i.e. it triggers through 'incidental' interactions like '.' (e.g. code completion) and Advertised but not triggered (e.g. the rename refactor example above, appears as a suggestion in the code editor but requires 1 more user action to activate) and Available on request (e.g. complex refactor or something that requires a user to provide more information, like extract method, can require multiple user actions to trigger)