[Dot shorthands]: Optional context types / context types of interest
Currently, dot shorthands are available only when the context type of the expression is known. However, due to how the Iterable API works, dot shorthands cannot be used, even if the type can be known.
Consider this example:
enum Foo {a, b, c}
void main() {
final values = <Foo>{.a, .c};
// Does not compile: `The static getter 'c' isn't defined for the context type 'Object'.`
final hasC = values.contains(.c);
}
Even though it could be solved by changing the API of contains and friends to accept T? instead of Object?, this change has been (understandably) rejected due to how generic collections can be used. However, since there are lints about using collections with "unrelated types", I understand that there is already a notion in the analyzer of something like a "type of interest" for collections. This information could be used in the analyzer to allow dot shorthands when such a type is available. Then, the above example would work with a hidden context type of Foo:
final Object anObject = 123;
// Still works
<Foo>{.a, .c}.contains(anObject);
// "Enhanced" handling of `Foo` values
<Foo>{.a, .c}.contains(.c);
This information could be used in the analyzer to allow dot shorthands when such a type is available
Not really. The analyzer cannot allow something that the language disallows.
The information the analyzer uses here is a heuristic that it's not part of the language. The language, in the language specification, does not know anything about Iterable.contains, even that it exists, but it is the language specification that defines which context types allow shorthands.
So to allow shorthands here, the special cases that the analyzer uses would have to be written into the language specification.
I'd be reluctant to add something that ad-hoc to the language. If it's useful to have an implicit context type in these places, it's probably useful in other places too, and the language should include a way to specify it inside the language, not hardcode a list of special cases.
The main issue here is the interface of contains. If you want to use shorthands there, you can make an extension:
extension<T> on List<T> {
bool typedContains(T value) => contains(value);
}
Then you can do list.contains(.c)