Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[macros] 馃煛 support for annotate_overrides #4925

Open
Tracked by #4881
pq opened this issue Apr 11, 2024 · 9 comments
Open
Tracked by #4881

[macros] 馃煛 support for annotate_overrides #4925

pq opened this issue Apr 11, 2024 · 9 comments
Assignees
Labels
new-language-feature P2 A bug or feature request we're likely to work on set-recommended Affects a rule in the recommended Dart rule set status-blocked Blocked from making progress by another (referenced) issue type-enhancement A request for a change that isn't a bug

Comments

@pq
Copy link
Member

pq commented Apr 11, 2024

Blocked on WIP in analyzer.

Invalid argument(s): InterfaceType(s) can only be created for declarations

  package:analyzer/src/dart/element/type.dart 479:7                        new InterfaceTypeImpl
  package:analyzer/src/dart/element/element.dart 3704:20                   InterfaceElementImpl.instantiate
  package:analyzer/src/dart/element/element.dart 3629:26                   InterfaceElementImpl.thisType
  package:linter/src/extensions.dart 348:42                                InhertanceManager3Extension.overriddenMember

https://dart-review.googlesource.com/c/sdk/+/362302

/fyi @scheglov

@pq pq added P2 A bug or feature request we're likely to work on new-language-feature labels Apr 11, 2024
@pq pq self-assigned this Apr 11, 2024
@github-actions github-actions bot added the set-recommended Affects a rule in the recommended Dart rule set label Apr 11, 2024
@pq pq added the status-blocked Blocked from making progress by another (referenced) issue label Apr 11, 2024
@pq pq changed the title [macros] support for annotate_overrides [macros] 馃煛 support for annotate_overrides Apr 11, 2024
@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label Apr 12, 2024
@scheglov
Copy link
Contributor

https://dart-review.googlesource.com/c/sdk/+/362660 probably unblock this.

@lrhn
Copy link
Member

lrhn commented Apr 14, 2024

What is the intended behavior for annotate_overrides and augmentations?

Should an augment void foo(){} be annotated with @override if there is a superclass member, or should only the base declaration be?
It's probably only the base declaration. Otherwise we might end up with multiple @override annotations on the same declaration, one for each augment.

Or rather, this sounds like a lint where only the final fully-augmented result matters. The @override can be added by any of the declarations of that name, as long as there is one at the end.
(That does depend on what the goal is. If the goal is to make it clear at the base declaration that it intends to override, then the annotation should be there.)

@bwilkerson
Copy link
Member

Or rather, this sounds like a lint where only the final fully-augmented result matters.

I agree and I think that's should be a general principle for any tooling checking for the absence of an annotation. Here's my reasoning.

According to the spec (https://github.com/dart-lang/language/blob/main/working/augmentation-libraries/feature-specification.md#metadata-annotations-and-macro-applications), metadata annotations and macro applications are cumulative across the base declaration and the augmentations.

So semantically, having an @override annotation on any one of the declarations in the chain ought to be sufficient. For most annotations, having them repeated would be harmless (but for macro applications it generally won't be harmless). That being the case, I don't think we want to require any annotation to be duplicated, nor do we want to dictate which declaration the annotation is physically associated with. (We might see common style evolve in the community, in which case we might later want to add a lint to enforce that style, but I think it's too early for that at this point.)

I suspect that in this case the intent of the work item is to only report the lint on the base declaration. That would also mean that our existing fix will continue to work without changes.

If the goal is to make it clear at the base declaration that it intends to override, then the annotation should be there.

I believe the goal of the lint is to ensure that (a) users are aware if a method starts to override a method added to a supertype, and (b) that users will be aware if a method that was added in order to override a method from a supertype is no longer needed because the method has been removed.

But I do think that it's an interesting UX question: will it be confusing to users to have annotations on an augmentation and hence not visible when looking at the base declaration? If so, we might want to consider ways for the IDE tooling to mitigate that confusion.

@pq
Copy link
Member Author

pq commented Apr 15, 2024

Should an augment void foo(){} be annotated with @override if there is a superclass member, or should only the base declaration be?

I think only the base declaration. My sense is that we should not lint on augmented fields or methods. (Just on fields and methods added by augmentation classes.)

I believe the goal of the lint is to ensure that (a) users are aware if a method starts to override a method added to a supertype, and (b) that users will be aware if a method that was added in order to override a method from a supertype is no longer needed because the method has been removed.

That's my understanding too.

@pq pq changed the title [macros] 馃煛 support for annotate_overrides [macros] support for annotate_overrides Apr 15, 2024
@pq pq removed the status-blocked Blocked from making progress by another (referenced) issue label Apr 15, 2024
copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Apr 16, 2024
Fixes: dart-lang/linter#4925

Change-Id: I7b9a3b5ab2c372bb29f990852edbf86ea49cd75b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362302
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
@pq
Copy link
Member Author

pq commented Apr 16, 2024

Fixed w/ dart-lang/sdk@d3d3efb

@pq pq closed this as completed Apr 16, 2024
@lrhn
Copy link
Member

lrhn commented Apr 25, 2024

I'd probably want to allow @override on augmentations too.

In particular, a macro can add a super-interface, and it should be able to add the appropriate override too.

@someMacro
class C {
  int get length => 42;
}
// from macro
augment class C implements Iterable<String> {
  //  ...
  @override
  augment int get length;
}

@pq pq reopened this Apr 25, 2024
@pq
Copy link
Member Author

pq commented Apr 25, 2024

Agreed. Currently, the above code will (wrongly) flag the initial declaration of C so I'm re-opening this to work on a fix. Thanks @lrhn!

@pq
Copy link
Member Author

pq commented Apr 25, 2024

See also: dart-lang/sdk#55579 -- If hasOverride considered augmentations, this would just work.

@bwilkerson
Copy link
Member

I'd probably want to allow @override on augmentations too.

We should definitely allow it.

The question is whether the lint should require it. I'm inclined to say "no" because the language doesn't require it and it doesn't seem unreasonable for users to not want to duplicate annotations. By "duplicate" I mean that, as far as I understand, writing (with the right boilerplate around it)

class C {
  @override
  String toString() {}
}

augment class C {
  @override
  augment String toString() {}
}

means that the method C.toString has two override annotations associated with it.

For override the duplication is harmless, but I could imagine an annotation where the duplication wasn't. Even for something like

@Deprecated('as of 2.12')
@Deprecated('as of 3.1')
void f() {}

where the duplication seems harmless, it raises questions of what the analyzer should show in the diagnostic when f is invoked somewhere. (Right now it shows the argument to the constructor in the message, but should it show multiple messages when there are multiple diagnostics? Don't know because nobody does that so we haven't needed to answer the question, but if those two annotations were on a declaration and an augmentation we might have to think about it.

The point of all that being that we don't know what the community will want to do stylistically, and I don't think we want to make the lint enforce one choice or the other at this point.

Maybe a different lint to enforce duplication would make sense if that becomes a common pattern.

copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Apr 26, 2024
Adds a failing test for the case where a `hasOverride` getter should consider augmentations.

See: dart-lang/linter#4925


Change-Id: I8d7e8f145d630abbef438a79076820613a801940
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/364623
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
@pq pq changed the title [macros] support for annotate_overrides [macros] 馃煛 support for annotate_overrides Apr 30, 2024
@pq pq added the status-blocked Blocked from making progress by another (referenced) issue label Apr 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-language-feature P2 A bug or feature request we're likely to work on set-recommended Affects a rule in the recommended Dart rule set status-blocked Blocked from making progress by another (referenced) issue type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants