Skip to content

Commit

Permalink
Fix mutation codegen (#3876)
Browse files Browse the repository at this point in the history
  • Loading branch information
r52 authored Dec 24, 2024
1 parent d7dc8e3 commit aaa38bf
Show file tree
Hide file tree
Showing 22 changed files with 320 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ class ChangeNotifierProviderElement<NotifierT extends ChangeNotifier?>
@override
final ChangeNotifierProvider<NotifierT> provider;

final _notifierNotifier = ProxyElementValueListenable<NotifierT>();
final _notifierNotifier = $ElementLense<NotifierT>();

void Function()? _removeListener;

@override
void create(Ref ref, {required bool didChangeDependency}) {
final notifierResult = _notifierNotifier.result = Result.guard(
final notifierResult = _notifierNotifier.result = $Result.guard(
() => provider._createFn(ref),
);

Expand Down Expand Up @@ -208,8 +208,7 @@ class ChangeNotifierProviderElement<NotifierT extends ChangeNotifier?>
@override
void visitChildren({
required void Function(ProviderElement element) elementVisitor,
required void Function(ProxyElementValueListenable element)
listenableVisitor,
required void Function($ElementLense element) listenableVisitor,
}) {
super.visitChildren(
elementVisitor: elementVisitor,
Expand Down
8 changes: 4 additions & 4 deletions packages/riverpod/lib/src/common/listenable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class _Listener<T> {
/// to subsets of the state exposed by a provider.
@internal
@optionalTypeArgs
class ProxyElementValueListenable<T> extends _ValueListenable<T> {
class $ElementLense<T> extends _ValueListenable<T> {
/// Directly obtain the value exposed, gratefully handling cases where
/// [result] is null or in error state.
T get value {
Expand All @@ -33,9 +33,9 @@ class ProxyElementValueListenable<T> extends _ValueListenable<T> {
/// The state associated with this notifier.
///
/// Modifying this property will notify listeners.
Result<T>? get result => _result;
Result<T>? _result;
set result(Result<T>? value) {
$Result<T>? get result => _result;
$Result<T>? _result;
set result($Result<T>? value) {
final previous = _result;
_result = value;

Expand Down
16 changes: 8 additions & 8 deletions packages/riverpod/lib/src/common/result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ import 'package:meta/meta.dart';
/// A T|Error union type.
@immutable
@internal
sealed class Result<State> {
sealed class $Result<State> {
/// The data case
// coverage:ignore-start
factory Result.data(State state) = ResultData;
factory $Result.data(State state) = ResultData;
// coverage:ignore-end

/// The error case
// coverage:ignore-start
factory Result.error(Object error, StackTrace stackTrace) = ResultError;
factory $Result.error(Object error, StackTrace stackTrace) = ResultError;
// coverage:ignore-end

/// Automatically catches errors into a [ResultError] and convert successful
/// values into a [ResultData].
static Result<State> guard<State>(State Function() cb) {
static $Result<State> guard<State>(State Function() cb) {
try {
return Result.data(cb());
return $Result.data(cb());
} catch (err, stack) {
return Result.error(err, stack);
return $Result.error(err, stack);
}
}

Expand All @@ -36,7 +36,7 @@ sealed class Result<State> {

/// The data case
@internal
class ResultData<State> implements Result<State> {
class ResultData<State> implements $Result<State> {
/// The data case
ResultData(this.state);

Expand Down Expand Up @@ -64,7 +64,7 @@ class ResultData<State> implements Result<State> {

/// The error case
@internal
class ResultError<State> implements Result<State> {
class ResultError<State> implements $Result<State> {
/// The error case
ResultError(this.error, this.stackTrace);

Expand Down
15 changes: 7 additions & 8 deletions packages/riverpod/lib/src/core/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ abstract class ProviderElement<StateT> implements Node {
var _didMount = false;

/* STATE */
Result<StateT>? _stateResult;
$Result<StateT>? _stateResult;

/// The current state of the provider.
///
Expand All @@ -138,7 +138,7 @@ abstract class ProviderElement<StateT> implements Node {
///
/// This is not meant for public consumption. Instead, public API should use
/// [readSelf].
Result<StateT>? get stateResult => _stateResult;
$Result<StateT>? get stateResult => _stateResult;

/// Returns the currently exposed by a provider
///
Expand All @@ -156,7 +156,7 @@ abstract class ProviderElement<StateT> implements Node {
///
/// This API is not meant for public consumption. Instead if a [Ref] needs
/// to expose a way to update the state, the practice is to expose a getter/setter.
void setStateResult(Result<StateT> newState) {
void setStateResult($Result<StateT> newState) {
if (kDebugMode) _debugDidSetState = true;

final previousResult = stateResult;
Expand Down Expand Up @@ -344,7 +344,7 @@ This could mean a few things:
} catch (err, stack) {
if (kDebugMode) _debugDidSetState = true;

_stateResult = Result.error(err, stack);
_stateResult = $Result.error(err, stack);
triggerRetry(err);
} finally {
_didBuild = true;
Expand Down Expand Up @@ -428,8 +428,8 @@ The provider ${_debugCurrentlyBuildingElement!.origin} modified $origin while bu
}

void _notifyListeners(
Result<StateT> newState,
Result<StateT>? previousStateResult, {
$Result<StateT> newState,
$Result<StateT>? previousStateResult, {
bool checkUpdateShouldNotify = true,
bool isMount = false,
}) {
Expand Down Expand Up @@ -805,8 +805,7 @@ The provider ${_debugCurrentlyBuildingElement!.origin} modified $origin while bu
/// [Ref.listen] multiple times to an element, it may be visited multiple times.
void visitChildren({
required void Function(ProviderElement element) elementVisitor,
required void Function(ProxyElementValueListenable element)
listenableVisitor,
required void Function($ElementLense element) listenableVisitor,
}) {
void lookup(Iterable<ProviderSubscriptionWithOrigin> children) {
for (final child in children) {
Expand Down
11 changes: 5 additions & 6 deletions packages/riverpod/lib/src/core/modifiers/future.dart
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ mixin FutureModifierElement<StateT> on ProviderElement<AsyncValue<StateT>> {

/// An observable for [FutureProvider.future].
@internal
final futureNotifier = ProxyElementValueListenable<Future<StateT>>();
final futureNotifier = $ElementLense<Future<StateT>>();
Completer<StateT>? _futureCompleter;
Future<StateT>? _lastFuture;
AsyncSubscription? _cancelSubscription;
Expand Down Expand Up @@ -270,7 +270,7 @@ mixin FutureModifierElement<StateT> on ProviderElement<AsyncValue<StateT>> {

@override
@protected
void setStateResult(Result<AsyncValue<StateT>> newState) {
void setStateResult($Result<AsyncValue<StateT>> newState) {
newState.requireState.map(
loading: onLoading,
error: onError,
Expand Down Expand Up @@ -314,7 +314,7 @@ mixin FutureModifierElement<StateT> on ProviderElement<AsyncValue<StateT>> {
);
_futureCompleter = null;
} else {
futureNotifier.result = Result.data(
futureNotifier.result = $Result.data(
Future.error(
value.error,
value.stackTrace,
Expand All @@ -336,7 +336,7 @@ mixin FutureModifierElement<StateT> on ProviderElement<AsyncValue<StateT>> {
completer.complete(value.value);
_futureCompleter = null;
} else {
futureNotifier.result = Result.data(Future.value(value.value));
futureNotifier.result = $Result.data(Future.value(value.value));
}
}

Expand Down Expand Up @@ -515,8 +515,7 @@ mixin FutureModifierElement<StateT> on ProviderElement<AsyncValue<StateT>> {
@override
void visitChildren({
required void Function(ProviderElement element) elementVisitor,
required void Function(ProxyElementValueListenable element)
listenableVisitor,
required void Function($ElementLense element) listenableVisitor,
}) {
super.visitChildren(
elementVisitor: elementVisitor,
Expand Down
18 changes: 9 additions & 9 deletions packages/riverpod/lib/src/core/modifiers/select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,30 @@ class _ProviderSelector<InputT, OutputT, OriginT>
/// The selector applied
final OutputT Function(InputT) selector;

Result<OutputT> _select(Result<InputT> value) {
$Result<OutputT> _select($Result<InputT> value) {
if (kDebugMode) _debugIsRunningSelector = true;

try {
return switch (value) {
ResultData(:final state) => Result.data(selector(state)),
ResultData(:final state) => $Result.data(selector(state)),
ResultError(:final error, :final stackTrace) =>
Result.error(error, stackTrace),
$Result.error(error, stackTrace),
};
} catch (err, stack) {
return Result.error(err, stack);
return $Result.error(err, stack);
} finally {
if (kDebugMode) _debugIsRunningSelector = false;
}
}

void _selectOnChange({
required InputT newState,
required Result<OutputT>? lastSelectedValue,
required $Result<OutputT>? lastSelectedValue,
required void Function(Object error, StackTrace stackTrace) onError,
required void Function(OutputT? prev, OutputT next) listener,
required void Function(Result<OutputT> newState) onChange,
required void Function($Result<OutputT> newState) onChange,
}) {
final newSelectedValue = _select(Result.data(newState));
final newSelectedValue = _select($Result.data(newState));
if (lastSelectedValue == null ||
!lastSelectedValue.hasState ||
!newSelectedValue.hasState ||
Expand Down Expand Up @@ -91,7 +91,7 @@ class _ProviderSelector<InputT, OutputT, OriginT>
}) {
onError ??= Zone.current.handleUncaughtError;

Result<OutputT>? lastSelectedValue;
$Result<OutputT>? lastSelectedValue;
final sub = provider.addListener(
node,
(prev, input) {
Expand All @@ -109,7 +109,7 @@ class _ProviderSelector<InputT, OutputT, OriginT>
onError: onError,
);

if (!weak) lastSelectedValue = _select(Result.guard(sub.read));
if (!weak) lastSelectedValue = _select($Result.guard(sub.read));

if (fireImmediately) {
_handleFireImmediately(
Expand Down
8 changes: 4 additions & 4 deletions packages/riverpod/lib/src/core/modifiers/select_async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ class _AsyncSelector<InputT, OutputT, OriginT>
/// The selector applied
final OutputT Function(InputT) selector;

Result<OutputT> _select(InputT value) {
$Result<OutputT> _select(InputT value) {
if (kDebugMode) _debugIsRunningSelector = true;

try {
return Result.data(selector(value));
return $Result.data(selector(value));
} catch (err, stack) {
return Result.error(err, stack);
return $Result.error(err, stack);
} finally {
if (kDebugMode) _debugIsRunningSelector = false;
}
Expand All @@ -43,7 +43,7 @@ class _AsyncSelector<InputT, OutputT, OriginT>
required bool fireImmediately,
required bool weak,
}) {
Result<OutputT>? lastSelectedValue;
$Result<OutputT>? lastSelectedValue;
Completer<OutputT>? selectedCompleter;
Future<OutputT>? selectedFuture;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ abstract class ClassProviderElement< //
@override
$ClassProvider<NotifierT, StateT, CreatedT> get provider;

final classListenable = ProxyElementValueListenable<NotifierT>();
final classListenable = $ElementLense<NotifierT>();

@mustCallSuper
@override
Expand All @@ -198,7 +198,7 @@ abstract class ClassProviderElement< //
}) {
final seamless = !didChangeDependency;

final result = classListenable.result = Result.guard(() {
final result = classListenable.result = $Result.guard(() {
final notifier = provider.create();
if (notifier._ref != null) {
throw StateError(alreadyInitializedError);
Expand Down Expand Up @@ -250,8 +250,7 @@ abstract class ClassProviderElement< //
@override
void visitChildren({
required void Function(ProviderElement element) elementVisitor,
required void Function(ProxyElementValueListenable element)
listenableVisitor,
required void Function($ElementLense element) listenableVisitor,
}) {
super.visitChildren(
elementVisitor: elementVisitor,
Expand Down
2 changes: 1 addition & 1 deletion packages/riverpod/lib/src/core/provider_subscription.dart
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ final class ProviderStateSubscription<StateT>
/// Deals with the internals of synchronously calling the listeners
/// when using `fireImmediately: true`
void _handleFireImmediately<StateT>(
Result<StateT> currentState, {
$Result<StateT> currentState, {
required void Function(StateT? previous, StateT current) listener,
required void Function(Object error, StackTrace stackTrace) onError,
}) {
Expand Down
8 changes: 4 additions & 4 deletions packages/riverpod/lib/src/core/proxy_provider_listenable.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
part of '../framework.dart';

class LazyProxyListenable<OutT, OriginT>
class $LazyProxyListenable<OutT, OriginT>
with ProviderListenable<OutT>, ProviderListenableWithOrigin<OutT, OriginT> {
LazyProxyListenable(this.provider, this._lense);
$LazyProxyListenable(this.provider, this._lense);

final ProviderBase<OriginT> provider;
final ProxyElementValueListenable<OutT> Function(
final $ElementLense<OutT> Function(
ProviderElement<OriginT> element,
) _lense;

Expand Down Expand Up @@ -100,7 +100,7 @@ class ProviderElementProxy<OutT, OriginT>

@override
final ProviderBase<OriginT> provider;
final ProxyElementValueListenable<OutT> Function(
final $ElementLense<OutT> Function(
ProviderElement<OriginT> element,
) _lense;

Expand Down
8 changes: 4 additions & 4 deletions packages/riverpod/lib/src/mutation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ abstract class $SyncMutationBase<

@override
void setData(StateT value) {
element.setStateResult(Result.data(value));
element.setStateResult($Result.data(value));
}
}

Expand All @@ -377,7 +377,7 @@ abstract class $AsyncMutationBase<

@override
void setData(StateT value) {
element.setStateResult(Result.data(AsyncData(value)));
element.setStateResult($Result.data(AsyncData(value)));
}
}

Expand All @@ -397,7 +397,7 @@ abstract class _MutationBase<
final Object? key;

ClassProviderElement<ClassT, StateT, Object?> get element;
ProxyElementValueListenable<MutationT> get listenable;
$ElementLense<MutationT> get listenable;

Object? get _currentKey => listenable.result?.stateOrNull?.key;

Expand Down Expand Up @@ -431,7 +431,7 @@ abstract class _MutationBase<
}

void _setState(MutationContext? mutationContext, MutationT mutation) {
listenable.result = Result.data(mutation);
listenable.result = $Result.data(mutation);

final obsContext = ProviderObserverContext(
element.origin,
Expand Down
Loading

0 comments on commit aaa38bf

Please sign in to comment.