-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Code-completion should recognize enum-like classes and constructor like functions. #34847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What about static final or const fields of type int, double, num, String, bool for enum-like classes of those types? |
@zoechi I don't see how to find those. The hint provided above is the context type, so you can check that exact type for constants or factories. If the context type is If we had type aliases with static members, say; typedef MyAliasForInt = int {
static const foo = 1;
static const bar = -1;
} then we might be able to complete those in a |
@lrhn If it is only about autocompletion, then an annotation could do that @Enum<int>()
abstract class MyEnum {
const int foo = 1;
const int bar = 2;
const bool otherConstMember = false;
MyEnum._();
}
This would make writing of the already verbose old-style enums even more cumbersome though. Type alias looks good, but I'd still prefer having the full capabilities of Dart classes available for enums. The ideal situation in my opinion would be if enum Color {
red, green, blue
} would lead to a class like abstract class Color implements Enum {
static const int red = Color(0);
static const int green = Color(1);
static const int blue = Color(2);
static const values = [red, green, blue];
// value could be `index` but might be weird if other types then `int` should be supported here
final int value;
const Color._(this.value);
factory Color.fromValue(int value) => values.firstWhere((v) => e.value == value); // or a switch/case for performance
@override
String toString() => '${super.toString()} - $value';
} and would allow to add everything that a normal class would allow enum Color {
red = Color(2, 'Red'),
green = Color(5, 'Green'),
blue = Color(9, 'Blue');
// additional static members
static const lightColors = [red, green];
// additional field
final String name;
// a different type for `value` (index in current Dart enums) might be useful as well not sure
// final double value;
// custom default enum constructor
// `const` could be implicit
const Color._(this.value, this.name);
// additional factory constructor
factory Color.fromName(String name) => values.firstWhere((v) => e.name == name);
// additional getter or method
String get nameAndValue => '$name - $value'
// custom toString
@override
String toString() => 'Color $name (value)';
} For issues discussed in dart-lang/language#50 I don't know if there are plans to add support for custom casts to Dart that would allow
to make conversion between |
What I would like to add to this, if we could annotate classes with enum, is to provide type checking as enums do. class Colors {
static const String red = "red";
static const String blue = "blue";
List<String> values = [red, blue];
} I would like to run a check to see if the value I'm encountering was from my Colors class, even though it evaluates to a |
Something like this? I have no idea about any of the technical details about implementation, but being able to extend an enum would be great. https://pub.dartlang.org/documentation/enums/latest/enums/Enum-class.html |
I think this is partially done in #40699. If the servers "Suggestion Sets" are enabled and the class is in another file, the static members are suggested via the suggestion sets: It doesn't work if they're in the same file (see |
With b253c4a (added for the new / current completion protocol) we suggest any static fields. The fields don't have to be declared in the same class as the context type, not If you know the name of the constant, you can start typing it. What is still missing.
|
It would be good to get some data here to see how many additional suggestions we're likely to introduce.
I'd love to see that. I don't know whether clients currently allow for that, though.
The context type (type matching) should also be used for local variables, so I would have expected that to improve the situation. (And maybe it does, just not by enough.) But I agree that we need to do some statistical analysis. The current relevance scores are based on very old-style code and need to be updated. |
I'm not sure if I understand this correctly, do you mean filtering for things where either the class or constant names contain the prefix (so typing dou^ would keep both constants from double and constants containing
VS Code will always apply a fuzzy search over the "filterText" (which defaults to the label if we don't set it.. usually we set it to the label minus any signature/details). That means if you type |
@alexander-doroshko Is this something we could also do in IntelliJ? |
That's cool! But I think Konstantin's thought was about being able to suggest something like |
We have alternatives how to filter
The option (4) seem to be most flexible. One issue with this, is that fuzzy matching implementation that we have in DAS, requires that the first letter must match. So, if we match But this also depends on what clients will do for fuzzy matching. |
That's not entirely true. :-) If DAS filters out a suggestion then the client can't decide to not filter it out. So I think on the server side the right behavior is to take into account how the clients will filter. Hence my interest in knowing how the clients will behave. |
The current code completion suggests
EnumClass.foo
in anEnumClass
typed context andFoo.constructorName
in aFoo
typed context. For all other static members of a class, you have to first write theClassName
before code completion will suggest the static members.I suggest expanding this favoritism:
SomeType
with a type that is a sub-type ofSomeType
in aSomeType
typed context, andSomeType
with a return type that is a sub-type ofSomeType
in aSomeType
typed context.That will treat any final static value (or even just the const ones) on a class with that class's type as a canonical instance of the class, and treat any static method on a class returning that class's type as a factory method.
This would allow user written enum classes to match language level enums in discoverability and usability, and it would allow allow factory functions to be recognized without them needing to be factory constructors.
It will also, for example, mean that
double x =
will suggestdouble.nan
anddouble.parse
, which are both classical examples of double expression you might want to complete with. Parse functions currently have worse discoverability than constructors (say, forUri
), even if they are likely to be the correct function to call in many cases.The text was updated successfully, but these errors were encountered: