-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Request] Warn when using private members of the same interface but a different instance #48918
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
To me, that sounds more like a lint than a warning, because there are risks of false positives. The |
I suspect that this approach would result in a lot of false positives, because I think there are plenty of times when it's valid to write a class (with private members) that you don't intend other users to implement.
But this approach, with a bit of refinement, would be less prone to false positives. I think it would also put the onus on the person attempting to implement a class rather than the person writing the class, which seems better to me. The one refinement that comes to mind is that it's only a problem if the private members of the class being implemented are being accessed on some object other than |
The problem here is that having a library private member should be invisible outside of that library. It's not part of the DartDoc and not discoverable, and you are free to change it between versions with nobody being able to tell the difference. Also, it would introduce a class without any implementable interface. That'd be great, but we may want to introduce that feature a little more formally, as something you can request, and not just as a side-effect of having private instance members. The current behavior is permissive. Not surprising, since it has been with us since Dart 0. Basically: It's OK to call private members on objects if we know that the run-time instance of the object has the member.
There is no good solution because a super-class having a member that a sub-class don't is completely contrary to object oriented design. We could make them all non-virtual, but we do rely on overriding private members in private subclasses. |
I think the constraint that a given member should only be accessed on |
After posting this issue I've search around the language, linter and the sdk repositories to realise, my request here is more or less trying to solve the inability to explicitly forbid implementing a class which #46331, linter-3353, and language-704 propose to solve. And those would probably be a less false positive way of dealing with the issue described here. |
Consider the following example:
Running
dart run main.dart
issues the expected error:Unhandled exception: NoSuchMethodError: Class 'DecoratedAddable' has no instance getter '_value'. Receiver: Instance of 'DecoratedAddable' Tried calling: _value #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5) dart-lang/sdk#57147 DecoratedAddable._value (lib1.dart:2:13) dart-lang/sdk#57148 Addable.+ (lib1.dart:7:37) dart-lang/sdk#57149 main (main.dart:5:14) dart-lang/sdk#57150 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19) dart-lang/sdk#57151 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
My desire is if the analyzer could warn whenever you are using a private member of a different instance of a class which can be implemented by a foreign library. In this case, if a warning could be issue in
Addable
when performing:Addable(_value + addable._value);
thataddable._value
is unsafe since the passed inAddable
may be a different implementation.Of course if
Addable
was private this shouldn't warn since we can be certain all the fields will be implemented.This issue has been on my mind for quite some time since it requires you to be constantly focused on what you're doing with your classes.
To illustrate this point further. Here is at least one example of this issue in the sdk, in the
Duration
class:sdk/sdk/lib/core/duration.dart
Lines 193 to 201 in edb7fb4
and some more unsafe usages at other operators:
sdk/sdk/lib/core/duration.dart
Lines 223 to 233 in edb7fb4
While the fix is trivial here, as is, if a client wanted to, for some reason, decorate the
Duration
class, and throughimplements
rather thanextend
, these methods would fail.Another way to safe-guard against this issue, would be either that no public class that defines a private field / method can be implemented by a different library only extended. I assume this would require some specification changes.
The text was updated successfully, but these errors were encountered: