diff --git a/lib/src/builder.dart b/lib/src/builder.dart index 309e5b0a..7fd81d7f 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -1318,14 +1318,21 @@ class _MockClassInfo { if (parameter.isRequiredPositional || parameter.isOptionalPositional) { final superParameterType = _escapeCovariance(parameter, position: position); - final matchingParameter = _matchingParameter(parameter, - superParameterType: superParameterType, forceNullable: true); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: superParameterType, + // A parameter in the overridden method may be a wildcard, in which + // case we need to rename it, as we use the parameter when we pass + // it to `Invocation.method`. + defaultName: '_$position', + forceNullable: true, + ); if (parameter.isRequiredPositional) { builder.requiredParameters.add(matchingParameter); } else { builder.optionalParameters.add(matchingParameter); } - invocationPositionalArgs.add(refer(parameter.displayName)); + invocationPositionalArgs.add(refer(matchingParameter.name)); position++; } else if (parameter.isNamed) { final superParameterType = @@ -1712,12 +1719,14 @@ class _MockClassInfo { {required analyzer.DartType superParameterType, String? defaultName, bool forceNullable = false}) { + final parameterHasName = parameter.name.isNotEmpty && parameter.name != '_'; assert( - parameter.name.isNotEmpty || defaultName != null, - 'parameter must have a non-empty name, or non-null defaultName must be ' - 'passed, but parameter name is "${parameter.name}" and defaultName is ' - '$defaultName'); - final name = parameter.name.isEmpty ? defaultName! : parameter.name; + parameterHasName || defaultName != null, + 'parameter must have a non-empty name, or non-null defaultName must be ' + 'passed, but parameter name is "${parameter.name}" and defaultName is ' + '$defaultName', + ); + final name = !parameterHasName ? defaultName! : parameter.name; return Parameter((pBuilder) { pBuilder.name = name; if (!superParameterType.containsPrivateName) { @@ -1980,8 +1989,13 @@ class _MockClassInfo { assert(setter.parameters.length == 1); final parameter = setter.parameters.single; + // The parameter in the overridden setter may be a wildcard, in which case + // we need to rename it, as we use the parameter when we pass it to + // `Invocation.setter`. + final parameterName = + parameter.displayName == '_' ? '_value' : parameter.displayName; builder.requiredParameters.add(Parameter((pBuilder) { - pBuilder.name = parameter.displayName; + pBuilder.name = parameterName; if (!parameter.type.containsPrivateName) { pBuilder.type = _typeReference(parameter.type, forceNullable: true, overrideVoid: true); @@ -2012,7 +2026,7 @@ class _MockClassInfo { final invocation = referImported('Invocation', 'dart:core').property('setter').call([ refer('#$name'), - refer(parameter.displayName), + refer(parameterName), ]); final returnNoSuchMethod = refer('super') .property('noSuchMethod') diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart index 5ae98b85..4c2d0d46 100644 --- a/test/builder/auto_mocks_test.dart +++ b/test/builder/auto_mocks_test.dart @@ -1364,7 +1364,6 @@ void main() { test('prefixes parameter type on generic function-typed parameter', () async { await expectSingleNonNullableOutput( dedent(r''' - import 'dart:async'; class Foo { dynamic m(void Function(Foo f) a) {} } @@ -1377,7 +1376,6 @@ void main() { test('prefixes return type on generic function-typed parameter', () async { await expectSingleNonNullableOutput( dedent(r''' - import 'dart:async'; class Foo { void m(Foo Function() a) {} } @@ -1389,7 +1387,6 @@ void main() { test('prefixes parameter type on function-typed parameter', () async { await expectSingleNonNullableOutput( dedent(r''' - import 'dart:async'; class Foo { void m(void a(Foo f)) {} } @@ -1402,7 +1399,6 @@ void main() { test('prefixes return type on function-typed parameter', () async { await expectSingleNonNullableOutput( dedent(r''' - import 'dart:async'; class Foo { void m(Foo a()) {} } @@ -1411,6 +1407,20 @@ void main() { ); }); + test('renames wildcard parameters', () async { + await expectSingleNonNullableOutput( + dedent(r''' + class Foo { + void m(int _, int _) {} + } + '''), + _containsAllOf( + 'void m(int? _0, int? _1) => super.noSuchMethod(Invocation.method(', + 'Invocation.method(#m, [_0, _1])', + ), + ); + }); + test('widens the type of parameters to be nullable', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2046,6 +2056,23 @@ void main() { ); }); + test('overrides nullable instance setters with wildcard parameters', + () async { + await expectSingleNonNullableOutput( + dedent(''' + class Foo { + void set m(int? _) {} + } + '''), + _containsAllOf(dedent2(''' + set m(int? _value) => super.noSuchMethod( + Invocation.setter(#m, _value), + returnValueForMissingStub: null, + ); + ''')), + ); + }); + test('overrides inherited non-nullable instance setters', () async { await expectSingleNonNullableOutput( dedent('''