Class _buildMockClass()

in lib/src/builder.dart [828:894]


  Class _buildMockClass() {
    final typeToMock = mockTarget.classType;
    final classToMock = mockTarget.classElement;
    final classIsImmutable = classToMock.metadata.any((it) => it.isImmutable);
    final className = classToMock.name;

    return Class((cBuilder) {
      cBuilder
        ..name = mockTarget.mockName
        ..extend = referImported('Mock', 'package:mockito/mockito.dart')
        // TODO(srawlins): Refer to [classToMock] properly, which will yield the
        // appropriate import prefix.
        ..docs.add('/// A class which mocks [$className].')
        ..docs.add('///')
        ..docs.add('/// See the documentation for Mockito\'s code generation '
            'for more information.');
      if (classIsImmutable) {
        cBuilder.docs.add('// ignore: must_be_immutable');
      }
      // For each type parameter on [classToMock], the Mock class needs a type
      // parameter with same type variables, and a mirrored type argument for
      // the "implements" clause.
      var typeArguments = <Reference>[];
      if (typeToMock.hasExplicitTypeArguments) {
        // [typeToMock] is a reference to a type with type arguments (for
        // example: `Foo<int>`). Generate a non-generic mock class which
        // implements the mock target with said type arguments. For example:
        // `class MockFoo extends Mock implements Foo<int> {}`
        for (var typeArgument in typeToMock.typeArguments) {
          typeArguments.add(_typeReference(typeArgument));
        }
      } else if (classToMock.typeParameters != null) {
        // [typeToMock] is a simple reference to a generic type (for example:
        // `Foo`, a reference to `class Foo<T> {}`). Generate a generic mock
        // class which perfectly mirrors the type parameters on [typeToMock],
        // forwarding them to the "implements" clause.
        for (var typeParameter in classToMock.typeParameters) {
          cBuilder.types.add(_typeParameterReference(typeParameter));
          typeArguments.add(refer(typeParameter.name));
        }
      }
      cBuilder.implements.add(TypeReference((b) {
        b
          ..symbol = classToMock.name
          ..url = _typeImport(mockTarget.classElement)
          ..types.addAll(typeArguments);
      }));
      if (!mockTarget.returnNullOnMissingStub) {
        cBuilder.constructors.add(_constructorWithThrowOnMissingStub);
      }

      // Only override members of a class declared in a library which uses the
      // non-nullable type system.
      if (!sourceLibIsNonNullable) {
        return;
      }
      final substitution = Substitution.fromInterfaceType(typeToMock);
      final members =
          inheritanceManager.getInterface(classToMock).map.values.map((member) {
        return ExecutableMember.from2(member, substitution);
      });
      cBuilder.methods
          .addAll(fieldOverrides(members.whereType<PropertyAccessorElement>()));
      cBuilder.methods
          .addAll(methodOverrides(members.whereType<MethodElement>()));
    });
  }