-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
In Dart, private members cannot be implemented outside of their declaring library, and as such, using implements A where A has a private member that is accessed outside of it's class can easily create an invalid class state; other types assume subtype A will always have a private member that it cannot have by definition.
An example described by @jakemac53:
// a.dart
class A {
int get _private => 0;
}
void foo(A a) => print(a._private);// b.dart
import 'a.dart';
// OK, no hints/lints/compile issues.
class B implements A {
// Even if this was commented-back in it would not help.
// int get _private => 0;
}I'd like to suggest a lint (that hopefully we add to recommended sets as it matures), which I'm naming avoid_private_access_on_open_classes (but the name is not important to me, only the semantics), it would flag private members accessed outside of their declaring class or sub-classes declared in the declaring library:
class A {
int get _private => 0;
@override
// OK
String toString() => 'A: $_private';
}
class B extends A {
@override
// OK
String toString() => 'B: $_private';
}
void foo(A a) {
// LINT: avoid_private_access_on_open_classes
print(a._private);
}
class C {
final A a;
C(this.a);
@override
// LINT: avoid_private_access_on_open_classes
String toString() => 'C: ${a._private}';
}
final class D {
int get _private => 0;
}
void d(D d) {
// OK, class is final.
print(d._private);
}
base class E {
int get _private => 0;
}
void e(E e) {
// OK, class is base.
print(e._private);
}
abstract class F {
int get _private;
@override
// LINT: _private is not implemented, and F is open.
String toString() => 'F: $_private';
}The error message/quick-fixes could suggest:
- Making
Afinal - Making
Abase - Making
_privatepublic - Silencing the lint with an
// ignoreif the developer knows this type is not truly API public
User-land issue: flutter/flutter#148692.