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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add protected. #2571

Closed
v0fbu1vm opened this issue Oct 13, 2022 · 6 comments
Closed

Add protected. #2571

v0fbu1vm opened this issue Oct 13, 2022 · 6 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@v0fbu1vm
Copy link

Please add protected. This feature is killing me. It's so necessary.

@v0fbu1vm v0fbu1vm added the feature Proposed language feature that solves one or more problems label Oct 13, 2022
@jakemac53
Copy link
Contributor

jakemac53 commented Oct 13, 2022

You can use @protected https://pub.dev/documentation/meta/latest/meta/protected-constant.html. It isn't language/runtime enforced, but will give analysis errors if people use it.

I think adding a true language feature for this gets complicated due to dynamic invocations (do you add a runtime check? how much additional info do you have to encode in shipped binaries to support that check?).

@lrhn
Copy link
Member

lrhn commented Oct 13, 2022

The thing that make it hard is indeed dynamic invocation. And everything having interfaces.

Dart does not have an access model that statically checks if you are allowed to call a member. If you can name it, you can call it. Library private members are designed such that you cannot name them from outside the library.

It's possible to do something similar to protected in Dart, but it won't be precisely the same as in, say, Java. In Java, the member is accessible on the class type to any code in a class extending the declaring class. In Dart, the members of a class is the same as the members of its interface, we don't have separate names for the two. So we can't distinguish types extending a class from those implementing it, all types are interface types.

What I'd do instead is to allow:

protected memberDecl;

to declare a member which exist only on the class, and is not available in the interface. It's also not available for dynamic invocation. The only way to actually invoke the member is to call it as a member of this (or super if inherited).

class Foo {
  protected int x = 0;
}
class Bar extends Foo {
  // "inherits" protected x.
  void inc() {
    this.x++;
  }
}

Subclasses can override the member normally, and access it.

To everybody else, the interface of Foo has no x member, and an instance of Foo or Bar has no x member either (if you check using dynamic invocations). The only access to x is found by going through the this reference of another instance method on a class extending the original declaring class.

Then it gest complicated.

Can a subclass make a non-protected member with the same name? (Maybe.)
Does it override the protected member (subject to the rules for valid overrides), or can it have a different signature? (.... likely the former. So you can publish a protected member.)
Can you protect a public member? (Probably not.)
If we choose to allow the subclass to have a non-protected member with the same name and a different signature, can you then declare both? (No!)
Can mixins declare protected members? (Probably. But they can't access protected members of their super-interfaces.)
What if two mixins with protected members conflict when mixed into the same class? (Probably a compile-time error.)
Can you make a protected static member? (No. That's where the difference from, e.g., Java shows. This is not about where the code calling the method is, but how it's called.)

@lrhn lrhn changed the title For the love of god, add protected. Add protected. Oct 13, 2022
@v0fbu1vm
Copy link
Author

I truly hate the fact that an object or whatever is showen outside of the surrounding directory. It's just so irritating. I only use dart because of flutter. In order to implement an architecture that makes sense. This feature is so necessary, I'm so tired of having to write 500-1000 lines in one single file inorder to eliminate confusion.

@Levi-Lesches
Copy link

I like @protected as a lint rule (that you can ignore) but I don't really see the need for it to be an enforced language construct. When I want to hide a member from other code I use private members but protected might be a bit too much granularity for a language that doesn't even distinguish between classes and interfaces.

Especially if you're just making your own Flutter code and not publishing a package -- what's so wrong with having some extra members exposed to your other code? If you want to be clear about usage, use @protected.

@jakemac53
Copy link
Contributor

jakemac53 commented Oct 13, 2022

I truly hate the fact that an object or whatever is shown outside of the surrounding directory.

What does this have to do with protected? It sounds like you are expecting Dart to just work exactly like whatever language you are used to (Java?), but it is a different language and likely has a different solution for what you are trying to do.

I would suggest using mostly private libraries (under lib/src) and then exporting the types you actually want exposed through a public library. But it is hard to understand exactly what you are looking for here.

Dart does not arbitrarily show symbols from entire directories.

@lrhn
Copy link
Member

lrhn commented Oct 13, 2022

There are times when you want to provide a base class with functionality intended for subclasses, but where that functionality should not be part of the public API that the subclasses expose.

There are workarounds to support that in Dart, but none as direct as protected in other languages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

4 participants