Code completion "not working" in `const` contexts

For the longest time, I have been frustrated by the following annoyance and I’d like to figure out if it’s “just me” or if people see this as a problem as well. (If so, there’s an existing issue I can point you to put a :+1: to.

Imagine you have some Flutter code like this:

    const Column(
      children: [
        Text('Headline'),
        Placeholder(),
      ],
    )

Then you finally have a real widget to put there instead of the Placeholder. Let’s say it’s called MyParagraph and it’s in a different Dart file.

If MyParagraph happens to have a const constructor, you’re good. You just delete Placeholder(), start typing MyParagraph(), and after a few strokes, code completion (the Dart analysis server) suggests the class and even imports it for you.

But things fall apart when the new symbol happens not to be const. This could happen for a bunch of reasons. The simplest one in our case is that the constructor has an assert in its initializer list. Then it can’t be const. But it could be that you’re trying to call a function or just plant a local (non-const) variable in there.

Anyway. Now, code completion will not suggest what you want. Because you’re in a const context, the analysis server (correctly!) understands that you can’t have a non-const thing in there. So it won’t even offer it to you — even after you’ve written 90% of the name.

What you have to do at that point is:

  1. Write the whole symbol name manually, and then ask for it to be imported (and then remove the const at the top).
    OR
  2. Go to the top to remove the const first, then go back to where you were. Now, code completion works.

Both cases regularly kick me out of flow. Today, I finally got sufficiently annoyed to file an issue only to find out there already is one.

To my surprise, it has zero thumbs up! I wonder if it’s just because I’m weird (e.g. other people correctly start by removing the const and never see this issue) or if it’s because it’s just this “death by a thousand paper cuts” so nobody looks for the issue (like I did for years at this point).

In any case, if you do find this annoying, please do add a :+1: to the issue on github. That makes the Dart team know that developers care about it. (And while you’re at it, also thumb up other issues that you care about.)

6 Likes

This is a new behavior I noticed recently (maybe 2 Dart (stable) versions ago?).

Also, I’m noticing another annoyance: the import now suggests the import plus the import using show (it just overcrowds the context menus and, AFAIK, all context menus come from Dart LSP, not Android Studio/VSCode extensions).

That’s one reason I always fighted when I was a VisualBASIC enthusiast some decades ago against C#: C# treats ; as a rule, while VB treats a line break using _ as an exception (so, my point was: when I need to do something that is exception in VB, I would type something, while in C# I would NOT type something in the exceptions, but wasting time typing something for the rules (the things that happens all the times)). Dart const seems like this: it would be better to inform a NON const constructor (maybe expliciting with new) and the compiler should always do a const constructor when it can (so, you must act on (few) exceptions instead of dealing with extra typing on 99.9999% of the cases).

Thanks for explaining it so well. I also complained about it on X and i was surprised not many people talk about this issue.

1 Like

Would you mind sharing the link?

This is definitely an issue, but I think recently there was a linter change that disables const by default, since they found the benefit was questionable. And in terms of devex, it improves multiple corner cases like this.

A hard habit to kick for sure, I still have const enabled but been considering making the switch

1 Like