-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add syntax to support object protected inheritance #3193
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
Added Area-Language, Triaged labels. |
This comment was originally written by [email protected] It occurs to me that this gets more interesting when you consider properties, because you can have different levels of protection on the getter and setter without giving them different names if you use object protection. In C# it is common to declare properties "public int Foo { get; private set; }" as this is what you want 90% of the time; a value that can be read by anyone but can only be set by the class. Dart doesn't have a short syntax like this, but a keyword akin to final on a field that makes it readable by any object but only writeable on this would be just as good for this case, and this covers a very large fraction of the use of properties. |
This comment was originally written by [email protected] The lacking of a way to protect functions from outside usage leads to more public functions and this could not be in the sense of small class interfaces... The use of Mixins oder the Strategy-Pattern doesn't solve the problem either. Sample: class JsonTestA implements Mixin1 { class JsonTestB extends JsonTestA with Mixin1 { testMixins() { test(' -> generate', () { // True if Mixin1 is in the same library, but if not, the test fails! There is no way to define a Template with private functions in a library and keep those function protected or private in subclasses defined in another library. |
This comment was originally written by [email protected] I'm sure the Dart engineers have thought about this heavily, but I did want to chime in that there are a growing number of workarounds in the Dart codebase due to lack of the protected namespace. Examples: ObservableList _recordChange -- private, requiring any subclass of ObservableList to copy several methods to use that functionality. I feel that the lack of protected makes the developer choose between either allowing their code to be extensible or keeping their public API clean. |
I pondered doing this as an annotation. See https://code.google.com/p/dart/issues/detail?id=6119 Zero effect on runtime behavior. It'd basically act like @deprecated. The editor/analyzer would show warnings if used outside of the class hierarchy. We get most of the benefits desired without having to make the type system more complicated. |
This comment was originally written by [email protected] Kevin, your proposal seems geared toward class-based protection, whereas this bug is related to object-based protection. While class-based protection is the more common form, I'm not aware of any use cases of it that wouldn't fit the object-based model better. The other reason to go with it is because it doesn't rely on the type system to determine visibility, it can be implemented fully in dart, whereas with class-based you'd want a more limited implementation like your annotation proposal. |
Removed this from the Later milestone. |
Removed Oldschool-Milestone-Later label. |
This comment was originally written by [email protected] New thread on this: https://groups.google.com/a/dartlang.org/d/topic/misc/cvjjgrwIHbU/discussion Lasse suggested a name-based approach, and while it's not necessary to go that route it would be very easy to implement that way. So for example, if we make all protected functions prefixed by "**", then all the compiler has to do is 1.) Do not mangle ** names at all, the way it does for _ names, and 2.) Forbid any calls to a __ member of any object other than this. No static analysis necessary. This variant has the potential feature that it would allow classes to call protected methods defined in subclasses. Or this could be prevented with some straightforward static analysis. Also, no one will accidentally override a protected method with a public method. |
This comment was originally written by [email protected] It occurs to me that you could support a combination of 1) object protected and 2) static class protected easily, and they could be used in combination as a way of doing class protected inheritence. It would be a little convoluted, but I don't know that it's a common use case anyway. So for example: // library A: class BaseClass { void _callProtectedFunc() => __protectedFunc(); // legal, calling protected func on this. // library B: class SubClass extends BaseClass { class Unrelated { |
This comment was originally written by @Emasoft Dart needs protected members. The very useful "protected" keyword is sorely missing. Currently many people are using workarounds to reproduce the protected state. For example here is a method to do it: library view; abstract class View { void activate() { abstract class ViewImpl implements View { @override ....In another library you write: library button; // notice, this is another library abstract class Button extends View { class ButtonImpl extends ViewImpl implements Button { ButtonImpl({this.title, HtmlElement host}) : super(host: host); ....and you can use it like this: final button = new Button(title: "Cancel", host: element); button.title // => cannot access! ....moreover, you can access the protected field in e.g. a unit test: // Instantiate the *Impl class to side-step the protection. In short, you hide your 'protected' methods in Impl classes. You can freely extend the implementation in different libraries. Source: http://stackoverflow.com/a/28513391/959398 Those workarounds are spreading and making the Dart code of many libraries unreadable and messy. Please add the "protected" keyword to the standard Dart syntax specifications. Thanks. |
This comment was originally written by @zoechi Doesn't need to be a keyword. An annotation @protected like @override would be enough. And it wouldn't require a language change at all. The analyzer complaining about violation of protected access and IDE's not listing them in autocompletion when not appropriate would be enough. |
This comment was originally written by @Emasoft Ok, but please do it quickly. Those workarounds are spreading and making the Dart code of many libraries unreadable and messy. |
the @Protected new value is only emiting a warning |
@YasserOJ you can configure the level yourself in analyzer_options.yaml |
thank you for the response @zoechi |
thank you for the response @zoechi |
A bit late, but the rule is called |
…3 revisions) https://dart.googlesource.com/dartdoc/+log/6b8b1c46da9a..ce5bd271eda9 2022-09-27 [email protected] Fix generic typedef pointing to typedef (#3193) 2022-09-27 [email protected] Unnamed libraries (#3189) 2022-09-27 [email protected] Make InheritingContainer._inheritedElements late final (#3191) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-doc-dart-sdk Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Dart Documentation Generator: https://github.com/dart-lang/dartdoc/issues To file a bug in Dart SDK: https://github.com/dart-lang/sdk/issues To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md Tbr: [email protected] Change-Id: I371d173b9225721274f4faf652b56ee4f9fa8082 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/261461 Commit-Queue: DEPS Autoroller <[email protected]> Commit-Queue: Devon Carew <[email protected]> Reviewed-by: Devon Carew <[email protected]>
This issue was originally filed by [email protected]
From discussion thread: https://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/6fd72014c119934d/6bed87932b58b762?lnk=raot#6bed87932b58b762
Some variant of protected inheritance would be useful, and a protected by object sort of inheritance would likely be better than protected by class, because class based protection leads to any subclass being able to mess with any other subclass in unexpected ways. Because object protected methods could be statically bound, there is no need to require a prefix to identify them, so the concept could be orthogonal to library privacy. Here is a proposed syntax:
class c {
// This is publicly visible
var publicFunc() {}
// This can be accessed by any code in this library
var _privateFunc() {}
// This can only be invoked on this
var this.protectedFunc() {}
// This can only be invoked on this by code in this library
var this._privateProtectedFunc() {}
}
The text was updated successfully, but these errors were encountered: