Closed shinayser closed 2 years ago
Without this feature, the extensions are completely useless! Do you have any plans to implement it?
As a workaround, we decided to put all extensions into a file and import it using a simple IntelliJ-based plugin we implemented. Basically, these are the steps:
.dart
file (let's say extensions.dart
) and export
all of your extension files in it like:
export 'an_extension.dart';
extensions.dart
in the file where you want to access the extension methods of an object.extensions.dart
each time tediously)
extensions.dart
and write the name of the class to import extensions.dart
.extensions.dart
using Fast Import -> Edit Path and import it with the help of a shortcut easily.You can also just start typing a class you know is in the extensions file, and then choose it from the list of suggested imports. I do this constantly with Provider
for example.
That's my temporary solution for that issue. The only think that I need to do is just start typing Ext...
and IntelliSense provides this stub class which holds reference to every extension file in my project.
@Afur and how much refactoring will you need to do in order to change your code after code assist will start working as intended?
@Afur and how much refactoring will you need to do in order to change your code after code assist will start working as intended?
Don't see any problem with this. Basically, it's even usefull to have all extensions collected together. Also, you can refactor incrementally. Anyway, after code completion is working as intended, you can just remove this abstract class and go through all errors in project and add correct imports using IDEA hints with hotkeys if you want to refactor all at once, but I don't see real necessity in it.
This is working for me now. I just upgraded Flutter to 2.10.0, the current stable channel. Dart version is 2.16.0.
Excellent! Glad to hear it, and thanks for letting us know.
I have seen this working in beta for a while, but it seems only when I write the entire method name perfectly, then I can import. Is that what everyone else is seeing?
extension Foo on String {
blah() => print(this);
}
Works with blah
though.
@esDotDev That is what I'm seeing as well. It's not very helpful.
When I saw the comment from @ipowell I was hoping that the extension would show in the autocomplete options. For example, in the below pic I would expect that myExtensionMethod
would show in the options window even though the file with the extension is not imported.
Yes, the piece to get extension members from extensions in libraries that are not yet imported still isn't complete.
Hey @bwilkerson this sounds a very important feature to add to the language, but considering the time I've opened the issue and it isn't fixed, I can assume that definitely is not an easy task.
Perhaps you can explain to us the difficulty of that issue? Maybe we can try to find a workaround and open an PR :)
It's definitely an important feature. The delay is primarily a result of (a) the current architecture of the code completion support and (b) limited resources.
When we first decided to start suggesting completions from libraries that weren't imported (about three years ago), we first tried the simple tactic of just adding the suggestions to the completion results. Unfortunately, this had some performance issues due to (a) having to process all of the elements from these un-imported libraries in order to create suggestions, and (b) the large amount of data that was being sent from the the server to the client (the IDE). These issues led to an unusable code completion experience.
So we designed a new protocol. The new protocol, which we're still using today, allowed the server to send all of the suggestions from un-imported libraries during the initial analysis and to keep it updated if the user changed which packages were available to a given package. That protocol was designed before extensions were introduced into the language and isn't flexible enough to support extension members.
We have considered changes to the protocol, and that's still an option that we're discussing, but we're currently looking at other approaches.
We changed our use of the protocol slightly, which is what allows us to suggest extension members if the package defining the extension is already imported. Initially we decided to use the same ahead-of-time computation of suggestions for imported libraries as for un-imported libraries. Now we're back to computing and sending suggestions from imported libraries at the time that completion suggestions are requested.
Recently we've seen some performance problems in code completion, and after some investigation we're now looking into a more radical change to the protocol. We're basically investigating using a protocol similar to the one LSP defines. The new protocol would allow the server to send back a small portion of the total list, allowing the client to control how much of the list should be returned.
If that work is successful, not only should it improve performance, but it should also allow us to compute suggestions from un-imported libraries when completions are requested, which should then allow us to include suggestions for extension members.
Thanks for the offer to help. I'm not the primary developer working on the new protocol, so I'm not sure how you could best contribute. I think that most of the work in the analysis server is completed and now we're working on finishing the work on the client side so that we can start testing it end-to-end.
Those are amazing news @bwilkerson. We're very excited to see the result of all your efforts!
I am a completion maniac myself, so if you folks need some guy like me to test that stuff, just call me :)
@scheglov can you confirm you implemented this?
Works for me.
Completion.
Quick fix.
Thanks to everybody that was involved in this feature. It works really smooth 👍🏽
Hi, How can I get to use this feature? I'm using vscode with latest flutter and Dart plug-in versions but this doesn't seem to work for me. Do I need to set a setting or update something? Thanks
As you can see, I use IntelliJ, but at least quick fix should work in VS Code as well. Does it work for you?
Sorry, I must have missed that. Yes the quick fix is working, but autocomplete doesn't work. Can we expect autocomplete to arrive to vscode soon?
@DanTup for VS Code completion insides :-)
@scheglov do we need to update dart to some specific version to get this working?
The changes, at least for quick fixes, were done in 979f3ea79ee188ec2e0c039a3186ebd28e0f636c. And for code completions about the same time. So, I expect that these are available in 2.17 Dart.
Ok I tested and it worked on some scenarios.
I believe I know why I haven't realized that change before and that is because our dependencies are transient.
I have a module that imports a dependencies module, and because of that the extensions doesn't work. Was it an intended behavior?
@shinayser my understanding is that this is intended. Any packages you directly depend on should be listed in your pubspec.yaml
(so you can set constraints and ensure they're always available even if other dependencies stop depending on them). As a result, completion/fixes/etc. will only suggest from those packages (if it didn't, code completion would contain a large number of classes from transient dependencies that not be wanted).
There's a related lint at https://dart-lang.github.io/linter/lints/depend_on_referenced_packages.html.
@DanTup Any news about this feature arriving to vscode? :)
@naamapps the quick-fix should already work today. Showing up in the completion list and auto-importing requires using a new completion API so isn't available in stable yet, although it is working behind a flag in the latest bleeding-edge/master SDK builds:
I'm not ready to make it default/remove the flag yet (I've still been fixing some issues fairly recently), but it's getting there.
Thanks for the quick reply @DanTup. Looking forward to use this feature 👍
@naamapps the quick-fix should already work today. Showing up in the completion list and auto-importing requires using a new completion API so isn't available in stable yet, although it is working behind a flag in the latest bleeding-edge/master SDK builds:
I'm not ready to make it default/remove the flag yet (I've still been fixing some issues fairly recently), but it's getting there.
This is great to hear. I'm looking forward to using this feature as well.
@shinayser my understanding is that this is intended. Any packages you directly depend on should be listed in your
pubspec.yaml
(so you can set constraints and ensure they're always available even if other dependencies stop depending on them). As a result, completion/fixes/etc. will only suggest from those packages (if it didn't, code completion would contain a large number of classes from transient dependencies that not be wanted).There's a related lint at https://dart-lang.github.io/linter/lints/depend_on_referenced_packages.html.
Thanks for your reply! I understand your point but it is a common pattern on some monorepo architectures to concentrate all the dependencies on a common "dependencies" module. So we would never get code completion on larger products because of this limitation.
You think I should open another issue to report that? Maybe we could think on a different solution. Maybe adding s tag to the pubspec to include those dependencies to the auto complete algorithm?
@shinayser there's some similar discussion at https://github.com/dart-lang/sdk/issues/43678#issuecomment-847782349. The suggestion was allowing the "common dependencies module" to record which of its dependencies it exposes to packages that depend on it. The response was that this should be filed against Pub, although I can't see any obvious issue that was raised about this, so perhaps it's worth filing one there to start a discussion.
I am opening this issue as @scheglov asked for at https://github.com/dart-lang/sdk/issues/25820#issuecomment-541972606
I am having problem with auto completing the new Extension Functions from dart 2.6.0. I have added a new file called "time.dart" with some extensions, like this:
My main file just can't auto complete it. If I try to quickfix the error I get the following:
As soon as I move the extensions to the same file as main, everything works:
If I add the import manually, it also works:
My Dart for Intellij plugin version is 192.6817.14