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

Edit mixin private properties #3010

Merged
merged 11 commits into from
May 12, 2021
Prev Previous commit
Next Next commit
Support editing private properties of mixins
  • Loading branch information
rrousselGit committed May 12, 2021
commit 6fd502c3ddcda5cb1543994a4e1685fe161ebdf1
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,27 @@ Future<List<ObjectField>> _parseFields(
final fields = instance.fields.map((field) async {
final owner = await eval.getClass(field.decl.owner, isAlive);

final ownerPackageName = tryParsePackageName(owner.library.uri);
String ownerUri;
String ownerName;
if (owner.mixin == null) {
ownerUri = owner.library.uri;
ownerName = owner.name;
} else {
final mixinClass = await eval.getClass(owner.mixin.typeClass, isAlive);

ownerUri = mixinClass.library.uri;
ownerName = mixinClass.name;
}

final ownerPackageName = tryParsePackageName(ownerUri);

return ObjectField(
name: field.decl.name,
isFinal: field.decl.isFinal,
ref: parseSentinel<InstanceRef>(field.value),
ownerName: owner.name,
ownerUri: owner.library.uri,
eval: ref.watch(libraryEvalProvider(owner.library.uri)),
ownerName: ownerName,
ownerUri: ownerUri,
eval: ref.watch(libraryEvalProvider(ownerUri)),
isDefinedByDependency: ownerPackageName != appName,
);
}).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:provider/single_child_widget.dart';

// ignore: unused_import, allows the tests to use functions from tester.dart
import 'tester.dart';
import 'mixin.dart';

void main() {
runApp(MyApp());
Expand Down Expand Up @@ -80,7 +81,7 @@ class _MyAppState extends State<MyApp> {
}
}

class Counter extends ChangeNotifier {
class Counter with ChangeNotifier, Mixin {
int _count = 0;
int get count => _count;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mixin Mixin {
int _privateMixinProperty = 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,41 @@ Future<void> runProviderControllerTests(FlutterTestEnvironment env) async {
});

group('Provider controllers', () {
test('can mutate private properties from mixins', () async {
final container = ProviderContainer();
addTearDown(container.dispose);

final sub = container.listen(
rawInstanceProvider(
const InstancePath.fromProviderId('0').pathForChild(
const PathToProperty.objectProperty(
name: '_privateMixinProperty',
ownerUri: 'package:provider_app/mixin.dart',
ownerName: 'Mixin',
),
),
).future,
);

var instance = await sub.read();

expect(
instance,
isA<NumInstance>().having((e) => e.displayString, 'displayString', '0'),
);

await instance.setter('42');

// read the instance again since it should have changed
instance = await sub.read();

expect(
instance,
isA<NumInstance>()
.having((e) => e.displayString, 'displayString', '42'),
);
});

test('rawSortedProviderNodesProvider', () async {
final container = ProviderContainer();
addTearDown(container.dispose);
Expand Down Expand Up @@ -217,6 +252,8 @@ Future<void> runProviderControllerTests(FlutterTestEnvironment env) async {
isA<ObjectField>()
.having((e) => e.ownerName, 'ownerName', 'Counter')
.having((e) => e.name, 'name', '_count')
.having((e) => e.ownerUri, 'ownerUri',
'package:provider_app/main.dart')
.having((e) => e.isFinal, 'isFinal', false)
.having((e) => e.isPrivate, 'isPrivate', true)
.having((e) => e.isDefinedByDependency,
Expand All @@ -225,10 +262,21 @@ Future<void> runProviderControllerTests(FlutterTestEnvironment env) async {
.having(
(e) => e.ownerName, 'ownerName', 'ChangeNotifier')
.having((e) => e.name, 'name', '_listeners')
.having((e) => e.ownerUri, 'ownerUri',
'package:flutter/src/foundation/change_notifier.dart')
.having((e) => e.isFinal, 'isFinal', false)
.having((e) => e.isPrivate, 'isPrivate', true)
.having((e) => e.isDefinedByDependency,
'isDefinedByDependency', true),
isA<ObjectField>()
.having((e) => e.ownerName, 'ownerName', 'Mixin')
.having((e) => e.name, 'name', '_privateMixinProperty')
.having((e) => e.ownerUri, 'ownerUri',
'package:provider_app/mixin.dart')
.having((e) => e.isFinal, 'isFinal', false)
.having((e) => e.isPrivate, 'isPrivate', true)
.having((e) => e.isDefinedByDependency,
'isDefinedByDependency', false),
]),
),
),
Expand Down