dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.25k stars 1.58k forks source link

Various issues with the documentation for @protected #40180

Open srawlins opened 4 years ago

srawlins commented 4 years ago

Here is the documentation for @protected. It has several issues:

  1. It doesn't address extensions explicitly. Instance members of the on type of an extension can be accessed with an implicit this, but an extension does not extend, implement or mix in the class enclosing such instance members.
  2. The docs say the annotation can annotate an "instance member", but then later says the instance member can only be "invoked" from other instance members. Is accessing a field an "invocation"? What about tearing off a method.
  3. The docs say that the instance member should only be accessed from "other instance members". What about constructors? It seems that it would make sense to allow a constructor to access such a member.
  4. The docs say that the instance member should only be invoked on this (explicitly or implicitly), but it seems that invoking on super would also be perfectly valid.
cedvdb commented 2 years ago

It doesn't address extensions explicitly. Instance members of the on type of an extension can be accessed with an implicit this, but an extension does not extend, implement or mix in the class enclosing such instance members.

When you use this you are hit with another lint rule to not use this explicitly. I believe extension should be allowed to reach protected members. By definition it's an extension, so it is still the same thing, it's just added behaviors.

My use case is that for each context we have a class like Restaurant, and for each use case within the context, the relevant method is added to the base class, like for example book(), in the booking use case. Using a BookableRestaurant would be a bit too verbose for my taste because of the constructors and factories involved.

lrhn commented 2 years ago

Since @protected is only an annotation, it cannot prevent access. It's not a real access barrier, just a statement of intent.

Because of that, I'd probably also allow extension methods to access the protected member on this. Could consider restricting it to extension members declared in the same library, treating them as part of the same domain. Because it's useful, not because it's what I'd do if it was a real language feature.

The question is whether the @protected annotation is trying to be its own thing, or to emulate what a real protected declaration might one day look like in Dart (if that ever happens). If we add that, I'm pretty sure extension methods will not be included.

(It's an access restriction, not a use-case restriction, so tear-offs should work too. Field access is invocations of the corresponding getter/setter. The body of a constructor should count as an instance-member context. Using super. should work too.)