Roslyn: Incorrect results when using "Show items from unimported namespaces" to complete generic types

Created on 25 Jun 2019  路  14Comments  路  Source: dotnet/roslyn

Steps to Reproduce:

I was trying to complete System.Collections.Generics.List, but I got the non-generic version of this type:

TypeCompletionForGenerics

Expected Behavior:
List<T> to be committed.

Actual Behavior:
List was committed.

Area-IDE Concept-Continuous Improvement IDE-IntelliSense

Most helpful comment

It continues completing, so you can filter down to any specific type.

To clarify, because I realize I wasn't super clear -

If you had a completion list with Foo, Foo<T> and Bar, you would see the following behaviors.

  • Type Foo<: list filters down to Foo< and does not commit as the < is part of the match
  • Type Bar<: list filters down to Bar, then the < commits it, and is itself inserted

IIRC we only implemented this for exact matches, not camelCase matches, so Fo< would still commit, but ideally this shouldn't commit either IMO.

All 14 comments

tag @genlu

I played around with this with the normal completion, looks like it doesn't need to handle this situation, and this completion works as expected if the generic and non-generic live in the same namespace because the non-generic adds the using required for the generic.

Yea, we have discussed this (and I totally forgot to file an issue, so thanks! :)). One potential solution we came up with is to keep track which namespaces/types are used in current project, and give that higher priority than others with same name.

Also, "List was committed" is the expected behavior here, since that's what you have selected from the list (or more accurately, selected for you). The actual problem is List<T> is not the selected one.

I think you need to rethink the design for generics in the completion window. In this world, it's now required that you know how generic types parameters are needed before you add "a using".

it's now required that you know how generic types parameters are needed before you add "a using".

I don't think this is surprising. If there are many lists in the world (regardless of whether they are generic or not), you'd have to pick the right one you wanted to get hte right import added. Wouldn't it make sense that you get the list, and you have to select the one from System.Collections.Generic in order to get that added?

Or am i missing something.

The impact is that with this feature turned on, it's become impossible to type List< without List being automatically selected and committed.

@davkean what were your keystrokes in the screen recording?

I typed 'L', 'I', 'S', 'T', '<'.

Ah, i see the concern Dave has. Note: i don't think this is specific to Lists or generic. If you type anything that now matches an importable type, and you hit a commit character, you will get the import added. Right? So even just typing something undefined, but hitting .dot, you could complete out to something unintended.

Should then perhaps be soft-selected? That way they never commit, except through explicit user action?

FWIW we handled this problem in MonoDevelop by suppressing commit when the typed character could be used in valid filtering matches, even if it was a commit character.

@genlu ^ This sounds like a great idea.

Does it dimiss the completion window, or keep completing?

It continues completing, so you can filter down to any specific type.

To clarify, because I realize I wasn't super clear -

If you had a completion list with Foo, Foo<T> and Bar, you would see the following behaviors.

  • Type Foo<: list filters down to Foo< and does not commit as the < is part of the match
  • Type Bar<: list filters down to Bar, then the < commits it, and is itself inserted

IIRC we only implemented this for exact matches, not camelCase matches, so Fo< would still commit, but ideally this shouldn't commit either IMO.

Thank @mhutch, I like this idea too. Will look into this.

Was this page helpful?
0 / 5 - 0 ratings