Skip to content

Commit

Permalink
Handle abstract/static
Browse files Browse the repository at this point in the history
  • Loading branch information
rrousselGit committed Dec 7, 2024
1 parent a6e7d7e commit 524815c
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
2 changes: 2 additions & 0 deletions packages/riverpod_analyzer_utils/lib/src/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ enum RiverpodAnalysisErrorCode {
providerOrFamilyExpressionParseError,
invalidRetryArgument,
mutationReturnTypeMismatch,
mutationIsStatic,
mutationIsAbstract,
}

class RiverpodAnalysisError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,29 @@ extension MutationMethodDeclarationX on MethodDeclaration {
final mutationElement = MutationElement._parse(element);
if (mutationElement == null) return null;

if (isStatic) {
errorReporter(
RiverpodAnalysisError(
'Mutations cannot be static.',
targetNode: this,
targetElement: element,
code: RiverpodAnalysisErrorCode.mutationIsStatic,
),
);
return null;
}
if (isAbstract) {
errorReporter(
RiverpodAnalysisError(
'Mutations cannot be abstract.',
targetNode: this,
targetElement: element,
code: RiverpodAnalysisErrorCode.mutationIsAbstract,
),
);
return null;
}

final expectedReturnType = thisOrAncestorOfType<ClassDeclaration>()!
.members
.whereType<MethodDeclaration>()
Expand Down
38 changes: 38 additions & 0 deletions packages/riverpod_analyzer_utils_tests/test/mutation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,42 @@ class SyncNotifier<T> extends _$SyncNotifier<T> {
),
);
});

testSource('rejects abstract/static mutations', source: r'''
import 'package:riverpod_annotation/riverpod_annotation.dart';
@riverpod
class Abstract extends _$Abstract {
@override
int build() => 0;
@mutation
Future<int> a();
@mutation
static Future<int> b() async => 42;
}
''', (resolver, unit, units) async {
final result =
await resolver.resolveRiverpodAnalysisResult(ignoreErrors: true);

expect(result.errors, hasLength(2));

expect(
result.errors,
everyElement(
isA<RiverpodAnalysisError>()
.having((e) => e.targetNode, 'node', isNotNull)
.having((e) => e.targetElement, 'element', isNotNull)
.having(
(e) => e.code,
'code',
anyOf(
RiverpodAnalysisErrorCode.mutationIsAbstract,
RiverpodAnalysisErrorCode.mutationIsStatic,
),
),
),
);
});
}
6 changes: 0 additions & 6 deletions packages/riverpod_generator/test/mutation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ import 'integration/mutation.dart';
import 'mock.dart';

void main() {
// Error:
// - Mutation returns a non-FutureOr<T> type
// - mutation is not on a notifier method
// mutation is static
// mutation is abstract

test('Can listen a mutation', () async {
final container = ProviderContainer.test();
final listener = ListenerMock<Simple$Delegated>();
Expand Down

0 comments on commit 524815c

Please sign in to comment.