diff --git a/lib/src/builder.dart b/lib/src/builder.dart index 33d36c67..71bbeb52 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -110,9 +110,7 @@ class MockBuilder implements Builder { // The generator appends a suffix to fake classes b.body.add(Code('// ignore_for_file: camel_case_types\n')); // The generator has to occasionally implement sealed classes - b.body.add(Code('// ignore_for_file: subtype_of_sealed_class\n')); - // The generator has to use `void`-typed arguments. - b.body.add(Code('// ignore_for_file: use_of_void_result\n\n')); + b.body.add(Code('// ignore_for_file: subtype_of_sealed_class\n\n')); b.body.addAll(mockLibraryInfo.fakeClasses); b.body.addAll(mockLibraryInfo.mockClasses); }); @@ -1676,8 +1674,8 @@ class _MockClassInfo { return Parameter((pBuilder) { pBuilder.name = name; if (!superParameterType.containsPrivateName) { - pBuilder.type = - _typeReference(superParameterType, forceNullable: forceNullable); + pBuilder.type = _typeReference(superParameterType, + forceNullable: forceNullable, overrideVoid: true); } if (parameter.isNamed) pBuilder.named = true; if (parameter.isRequiredNamed && sourceLibIsNonNullable) { @@ -1935,7 +1933,8 @@ class _MockClassInfo { builder.requiredParameters.add(Parameter((pBuilder) { pBuilder.name = parameter.displayName; if (!parameter.type.containsPrivateName) { - pBuilder.type = _typeReference(parameter.type, forceNullable: true); + pBuilder.type = _typeReference(parameter.type, + forceNullable: true, overrideVoid: true); } })); @@ -1997,7 +1996,10 @@ class _MockClassInfo { // TODO(srawlins): Contribute this back to a common location, like // package:source_gen? Reference _typeReference(analyzer.DartType type, - {bool forceNullable = false}) { + {bool forceNullable = false, bool overrideVoid = false}) { + if (overrideVoid && type.isVoid) { + return TypeReference((b) => b..symbol = 'dynamic'); + } if (type is analyzer.InterfaceType) { return TypeReference((b) { b diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart index fcfcca02..a6bc6907 100644 --- a/test/builder/auto_mocks_test.dart +++ b/test/builder/auto_mocks_test.dart @@ -3542,6 +3542,24 @@ void main() { ); }); }); + test('Void in argument type gets overriden to dynamic', () async { + final mocksContent = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' + class Foo { + void m(void x) {} + } + '''), + 'foo|test/foo_test.dart': dedent(r''' + import 'package:foo/foo.dart'; + import 'package:mockito/annotations.dart'; + + @GenerateMocks([Foo]) + void main() {} + '''), + }); + expect(mocksContent, contains('void m(dynamic x)')); + }); } TypeMatcher> _containsAllOf(a, [b]) => decodedMatches( diff --git a/test/builder/custom_mocks_test.dart b/test/builder/custom_mocks_test.dart index 4db4961e..71dc963f 100644 --- a/test/builder/custom_mocks_test.dart +++ b/test/builder/custom_mocks_test.dart @@ -1670,6 +1670,24 @@ void main() { ); }); }); + test('Void in argument type coming from type arg becomes dynamic', () async { + final mocksContent = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' + class Foo { + T m(T x) => x; + } + '''), + 'foo|test/foo_test.dart': dedent(r''' + import 'package:foo/foo.dart'; + import 'package:mockito/annotations.dart'; + + @GenerateMocks([], customMocks: [MockSpec>()]) + void main() {} + '''), + }); + expect(mocksContent, contains('void m(dynamic x)')); + }); } TypeMatcher> _containsAllOf(a, [b]) => decodedMatches(