-
Notifications
You must be signed in to change notification settings - Fork 170
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
Proposal: Generalize avoid_types_as_parameter_names
to include type parameters
#5066
Comments
Unfortunately, this is a breaking change. We'll need to assess the scope before we can decide whether the cost is worth the benefit (though I suspect that the cost will be low). |
Brian is right. As with all "false negatives", we have to be careful about impact. (This is a core lint too so all the more reason.) That said, this does seem like a good change to explore to me. To start, it'd be interesting to fix it as proposed and see if we detect any violations in the SDK, Flutter or Google3. |
I'd just fork the rule with a new name, |
Sam makes a good point. This is an option. I'm not sure it really saves us any work in the long run though (since deprecation and removal adds a bit of it's own work). Worth considering though! |
Would leaving |
Leaving it untouched would be easier, but worse for the user, by adding confusion about why there are two rules, and it would be worse for the team, who would have to maintain both. I don't think there is a reason we'd want to support the looser existing rule and a stricter new rule, and I don't know of a reason that a user would want the looser version. |
I agree with Sam. Finer control is really appealing (but comes at a cost). @eernstg: I'm curious if you've done any experimenting to see how much impact this would actually have? I'm guessing it doesn't happen that much in practice but it'd be interesting to get a better idea. |
No, I haven't implemented anything. I suspect that it wouldn't be hard to create a CL that changes |
Have you considered using language versioning with lints, so a change to a lint is only enabled for code when it changes to the new language version. (Adding warnings is not breaking. You can still compile and run a program with warnings, unless you turn warnings into errors, but that is a choice you make to make your build process stop on non-breaking changes. The change wasn't breaking.) We'll still have to fix all internal code, though. |
By "breaking", Brian means that the change may be excruciating to land. Since flutter CI turns red when a new static warning is reported, you have to clean up new violations in flutter before landing. Since flutter customer tests turn red when a new static warning is reported, you have to clean up new violations in flutter customer tests before landing. Same with the flutter engine, flutter plugins, Dart SDK, and all of google3. |
This is a case of people painting themselves into a corner. Warnings are not errors, otherwise they would have been errors. The thing is, warnings are not added to annoy people, but to help them. If a lint is enabled, it's because someone considers it important to satisfy the lint in their own code. If a tool gives a new warning, it's because it thinks it's important to look at that code. (Is the issue tooling? Could we have a marker on each lint warning that says when it was introduced, and then a build-system can choose to not turn warnings into errors if they're newer than 30 days, or whatever limit they want? |
I don't think there's anything surprising or wrong in introducing |
Here's a small experiment: https://dart-review.googlesource.com/c/sdk/+/381841. It extends One type of situation occurs several times: class A<X> {
static X myStaticMethod<X>(X x) => x; // LINT
} This is a violation of the generalized This might be OK because a static member has no access to the type parameters of the enclosing class, and hence it could make sense to copy the type parameter list of the class into a static method declaration "because it needs the same type parameters as the enclosing class". If it is considered to be OK then we'd need a special exception for this kind of situation. However, I'd prefer to report the situation even in this case. For instance, it could also be a source of confusion for a reader who thinks that an occurrence of In summary: The breakage isn't daunting. 😁 |
Here's a reason why we should probably recommend that developers do not shadow a class type parameter with a static member type parameter: class A<X> {
final X x;
A(this.x);
List<X> get asList => [this.x];
static List<X> asListStatic<X>(A<X> this_) => [this_.x];
}
void main() {
A<num> a = A<int>(1);
print(a.asList.runtimeType); // 'List<int>'.
print(A.asListStatic(a).runtimeType); // 'List<num>'.
} In other words, it is not safe to assume that it's "the same Updated summary: It's all good breakage! 😁 |
|
Note about a similar existing rule: avoid_shadowing_type_parameters explicitly allows "shadowing" a type parameter in a static element. See test: https://github.com/dart-lang/sdk/blob/main/pkg/linter/test/rules/avoid_shadowing_type_parameters_test.dart#L187 |
OK, 330 violations, 211 of them |
At this time, the lint implementation in https://dart-review.googlesource.com/c/sdk/+/381841 no longer reports the situation where a type variable of a static method shadows a type variable of the enclosing declaration (which is a class, mixin, mixin class, extension type, or extension). 106 violations. |
This CL renames a declaration in the test instance_creation.dart: The class `K` is renamed to `L`, and its type parameters are renamed from `A` and `B` to `S` and `T`. The point is that these changes eliminate situations which are linted with the update in dart-lang/linter#5066. Change-Id: Iac6b77dc8cfeebedef98a739817049afba1f41d3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382890 Commit-Queue: Erik Ernst <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
This CL removes an unused type parameter from a test in _macros. The type parameter gave rise to a warning from the lint `avoid_types_as_parameter_names` because it had the same name as a type in scope (`Declaration`). The type variable could also have been renamed, but it seems very unlikely that any other part of the system will break because the type parameter has been removed: The function is declared in a test, and nothing in the test depends on that type parameter in any way. See also dart-lang/linter#5066 for details. Change-Id: Ibc42c4a758f70564c9fe12f3bf2bfbb72e63e97d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/383600 Reviewed-by: Jake Macdonald <[email protected]>
Thanks to @martin-east for bringing up this topic.
Description
The lint
avoid_types_as_parameter_names
will report situations where a formal parameter declaration in a function or type alias declaration shadows a type declaration with the same name in an enclosing scope.This is a proposal to generalize that lint such that it also reports the same situation when the formal parameter is declared by a function type, and also when the formal parameter is a type parameter.
To Reproduce
Expected behavior
avoid_types_as_parameter_names
lints parameter names in function types and names of type parameters as well, when they shadow a type in an enclosing scope.Additional context
Positional parameter names in a function type are never the result of a lookup, so we might ignore them. Nevertheless, it is probably a mistake, and a source of confusion, if such parameters are specified to have a name which is also the name of a type in the enclosing scope, so it is probably a better idea to treat them just like all other parameters.
The text was updated successfully, but these errors were encountered: