-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[Extension type] Add a @redeclare
annotation
#53121
Comments
Sorry, what's the difference between overriding and redeclaring? |
Overriding is virtual, and replaces the existing method on all instances of the subclass, whether they are known to have the subclass interface or not. An override must have a compatible signature. A redeclaration doesn't need to have a compatible signature. It shadows the original when declared on an extension type which also implements a superior with a same-named member. The former is providing a specialized version of the overridden member, the latter is just providing a completely new member with the same name. The idea behind the warning here would be that the name collision might be accidental, and by making you provide an annotation, you can state that it was deliberate. Then we can warn you if you make an accidental shadowing, which is easier to do than an accidental override, since you don't have to match the signature, and we can warn you if you claim to be shadowing something, but isn't. I'm worried about the latter. Shadowing is unrelated to the thing it shadows, so if that goes away, it really only needs to be an info that the annotation is unnecessary. It doesn't change the meaning of the used-to-be-shadowing member. Making it a warning, which some will then make an error, is more fragile than necessary. Or make it a lint, so it's opt-in, unlike the unnecessary override warning. For the unannotated redeclaration, that could be a lint to, maybe the same one endless both. I won't put the Also consider allowing the use of |
Got it. |
I'm not sure where the "redeclare" name comes from. I'm not even sure we need the annotation, but if there is an audience for it, it's definitely a lint we can provide. I think "shadow" is a little too specific, and transitive (I'd expect it to say what it shadows). (If we allowed |
I comes from the feature specification, which says:
|
@pq wrote:
That would be great! I do think a case can be made for the ability to announce explicitly that a given redeclaration relationship is intended. In particular, it seems very plausible to me that some extension type hierarchies will be designed such that redeclarations never occur. Indeed, several of the early proposals about extension types (known as The motivation for avoiding redeclarations would be that a hierarchy with no redeclarations will behave in a manner which is more like the behavior of a class hierarchy: Assume that Developers and organizations who wish to outlaw redeclarations could then enable the lint and check that Conversely, other developers/organizations might prefer to allow redeclarations. In this case it would make sense to enable the lint and have the All in all, I think it's fair to say that |
A minor nit, unless someone cares deeply. :-) The approach we've consistently taken in the analyzer is that any diagnostics related to annotations are considered to be warnings (enabled by default) because the user has explicitly told us what their expectations are. If we add a declaration of But if we want a diagnostic that prohibits the use of |
That sounds fine to me: A warning to have |
OK, |
What a great discussion. Thanks for all the added consideration! I'll take a look at the annotation and diagnostic/lint work. Adding @MaryaBelanger for context: brace yourself for some doc reviews! 😉 |
@redeclare
annotation@redeclare
annotation
Do we anticipate a use case where only some redeclarations are meant to be disallowed? That is, should we allow specific declarations to be non-redeclarable? (Something analogous to @nonVirtual?) |
While that's certainly possible, my guess is that we should wait to add anything similar to |
I think this would be more like a type hierarchy thing than a member declaration thing: With In particular, with So it probably doesn't make much sense to avoid this kind of complexity on a per-member basis, it's more like a package level or organizational level decision. A lint which is enabled/disabled on a per-package basis would probably be fine for that purpose, and Finally, it should be noted that we've had // This is the one we know about.
extension on num {
void foo() => print("Good ole foo won't hurt a fly!");
}
// This one slipped under the radar.
extension on int {
void foo() => print("Hehe! I'll swat that one!");
}
void main() {
num n = 1;
n.foo(); // All flies ok.
if (n is! int) return;
n.foo(); // Oops!
} Of course, what I really want here is IDE support for dispatch visualization: Statically resolved invocations have pale blue background color, OO dispatched invocations have pale green background color, and dynamic invocations have blinking red background color. ;-) |
See: #53121 Change-Id: I812bc49b58cdf15e9c0c8bcc62a846b51f5dff70 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319100 Commit-Queue: Phil Quitslund <pquitslund@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
See: #53121 Change-Id: I994aac6c733704ac7adc4a7923ee733cdc77aacb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319561 Commit-Queue: Phil Quitslund <pquitslund@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
See: #53121 Change-Id: I39294952a3adf0f037417d6e04811e3294128e6d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320886 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Phil Quitslund <pquitslund@google.com>
See: #53121 Change-Id: I324f8a14820da2e9e5b714f9f1d88c647f9cfebc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/321424 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Phil Quitslund <pquitslund@google.com>
This annotation was shipped in meta 1.10.0. |
Extension types don't override but rather redeclare so we should probably discourage/disallow the use of the
@override
annotation on extension type members and provide an alternative annotation such as@redeclare
to communicate when an extension type member is intended to be redeclaring. (Along with that we should consider a lint, likeunnecessary_redeclare
to flag misplaced annotations (e.g., likeunnecesssary_overrides
)./cc @dart-lang/language-team @scheglov @bwilkerson @jacob314
The text was updated successfully, but these errors were encountered: