// Copyright 2019 Dart Mockito authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// @dart=2.9

import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart' as analyzer;
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:build/build.dart';
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'package:meta/meta.dart';
import 'package:mockito/src/version.dart';
import 'package:path/path.dart' as p;
import 'package:source_gen/source_gen.dart';

/// For a source Dart library, generate the mocks referenced therein.
///
/// Given an input library, 'foo.dart', this builder will search the top-level
/// elements for an annotation, `@GenerateMocks`, from the mockito package. For
/// example:
///
/// ```dart
/// @GenerateMocks([Foo])
/// void main() {}
/// ```
///
/// If this builder finds any classes to mock (for example, `Foo`, above), it
/// will produce a "'.mocks.dart' file with such mocks. In this example,
/// 'foo.mocks.dart' will be created.
class MockBuilder implements Builder {
  @override
  Future<void> build(BuildStep buildStep) async {
    if (!await buildStep.resolver.isLibrary(buildStep.inputId)) return;
    final entryLib = await buildStep.inputLibrary;
    if (entryLib == null) return;
    final sourceLibIsNonNullable = entryLib.isNonNullableByDefault;
    final mockLibraryAsset = buildStep.inputId.changeExtension('.mocks.dart');
    final mockTargetGatherer = _MockTargetGatherer(entryLib);

    var entryAssetId = await buildStep.resolver.assetIdForElement(entryLib);
    final assetUris = await _resolveAssetUris(
        buildStep.resolver, mockTargetGatherer._mockTargets, entryAssetId.path);

    final mockLibraryInfo = _MockLibraryInfo(mockTargetGatherer._mockTargets,
        assetUris: assetUris, entryLib: entryLib);

    if (mockLibraryInfo.fakeClasses.isEmpty &&
        mockLibraryInfo.mockClasses.isEmpty) {
      // Nothing to mock here!
      return;
    }

    final mockLibrary = Library((b) {
      // These comments are added after import directives; leading newlines
      // are necessary.
      // We don't properly prefix imported class names in doc comments.
      b.body.add(Code('\n\n// ignore_for_file: comment_references\n'));
      // The code_builder `asA` API unconditionally adds defensive parentheses.
      b.body.add(Code('// ignore_for_file: unnecessary_parenthesis\n\n'));
      b.body.addAll(mockLibraryInfo.fakeClasses);
      b.body.addAll(mockLibraryInfo.mockClasses);
    });

    final emitter = DartEmitter.scoped(
        orderDirectives: true, useNullSafetySyntax: sourceLibIsNonNullable);
    final rawOutput = mockLibrary.accept(emitter).toString();
    final mockLibraryContent = DartFormatter().format('''
// Mocks generated by Mockito $packageVersion from annotations
// in ${entryLib.definingCompilationUnit.source.uri.path}.
// Do not manually edit this file.

$rawOutput
''');

    await buildStep.writeAsString(mockLibraryAsset, mockLibraryContent);
  }

  Future<Map<Element, String>> _resolveAssetUris(Resolver resolver,
      List<_MockTarget> mockTargets, String entryAssetPath) async {
    final typeVisitor = _TypeVisitor();
    final seenTypes = <analyzer.InterfaceType>{};

    void addTypesFrom(analyzer.InterfaceType type) {
      // Prevent infinite recursion.
      if (seenTypes.contains(type)) {
        return;
      }
      seenTypes.add(type);
      type.element.accept(typeVisitor);
      // For a type like `Foo<Bar>`, add the `Bar`.
      (type.typeArguments ?? [])
          .whereType<analyzer.InterfaceType>()
          .forEach(addTypesFrom);
      // For a type like `Foo extends Bar<Baz>`, add the `Baz`.
      for (var supertype in type.allSupertypes) {
        addTypesFrom(supertype);
      }
    }

    for (var mockTarget in mockTargets) {
      addTypesFrom(mockTarget.classType);
    }

    final typeUris = <Element, String>{};

    for (var element in typeVisitor._elements) {
      if (element.library.isInSdk) {
        typeUris[element] = element.library.source.uri.toString();
        continue;
      }

      try {
        var typeAssetId = await resolver.assetIdForElement(element.library);

        if (typeAssetId.path.startsWith('lib/')) {
          typeUris[element] = typeAssetId.uri.toString();
        } else {
          typeUris[element] =
              p.relative(typeAssetId.path, from: p.dirname(entryAssetPath));
        }
      } on UnresolvableAssetException {
        // Asset may be in a summary.
        typeUris[element] = element.library.source.uri.toString();
        continue;
      }
    }

    return typeUris;
  }

  @override
  final buildExtensions = const {
    '.dart': ['.mocks.dart']
  };
}

/// An [Element] visitor which collects the elements of all of the
/// [analyzer.InterfaceType]s which it encounters.
class _TypeVisitor extends RecursiveElementVisitor<void> {
  final _elements = <Element>{};

  @override
  void visitClassElement(ClassElement element) {
    _elements.add(element);
    super.visitClassElement(element);
  }

  @override
  void visitFieldElement(FieldElement element) {
    _addType(element.type);
    super.visitFieldElement(element);
  }

  @override
  void visitMethodElement(MethodElement element) {
    _addType(element.returnType);
    super.visitMethodElement(element);
  }

  @override
  void visitParameterElement(ParameterElement element) {
    _addType(element.type);
    if (element.hasDefaultValue) {
      _addTypesFromConstant(element.computeConstantValue());
    }
    super.visitParameterElement(element);
  }

  @override
  void visitTypeParameterElement(TypeParameterElement element) {
    _addType(element.bound);
    super.visitTypeParameterElement(element);
  }

  /// Adds [type] to the collected [_elements].
  void _addType(analyzer.DartType type) {
    if (type == null) return;

    if (type is analyzer.InterfaceType) {
      _elements.add(type.element);
      (type.typeArguments ?? []).forEach(_addType);
    } else if (type is analyzer.FunctionType) {
      _addType(type.returnType);

      // [RecursiveElementVisitor] does not "step out of" the element model,
      // into types, while traversing, so we must explicitly traverse [type]
      // here, in order to visit contained elements.
      if (type.typeFormals != null) {
        for (var typeParameter in type.typeFormals) {
          typeParameter.accept(this);
        }
      }
      for (var parameter in type.parameters) {
        parameter.accept(this);
      }
      var aliasElement = type.aliasElement;
      if (aliasElement != null) {
        _elements.add(aliasElement);
      }
    }
  }

  void _addTypesFromConstant(DartObject object) {
    final constant = ConstantReader(object);
    if (constant.isNull ||
        constant.isBool ||
        constant.isInt ||
        constant.isDouble ||
        constant.isString ||
        constant.isType) {
      // No types to add from a literal.
      return;
    } else if (constant.isList) {
      for (var element in constant.listValue) {
        _addTypesFromConstant(element);
      }
    } else if (constant.isSet) {
      for (var element in constant.setValue) {
        _addTypesFromConstant(element);
      }
    } else if (constant.isMap) {
      for (var pair in constant.mapValue.entries) {
        _addTypesFromConstant(pair.key);
        _addTypesFromConstant(pair.value);
      }
    } else if (object.toFunctionValue() != null) {
      _elements.add(object.toFunctionValue());
    } else {
      // If [constant] is not null, a literal, or a type, then it must be an
      // object constructed with `const`. Revive it.
      var revivable = constant.revive();
      for (var argument in revivable.positionalArguments) {
        _addTypesFromConstant(argument);
      }
      for (var pair in revivable.namedArguments.entries) {
        _addTypesFromConstant(pair.value);
      }
      _addType(object.type);
    }
  }
}

class _MockTarget {
  /// The class to be mocked.
  final analyzer.InterfaceType classType;

  /// The desired name of the mock class.
  final String mockName;

  final bool returnNullOnMissingStub;

  _MockTarget(this.classType, this.mockName, {this.returnNullOnMissingStub});

  ClassElement get classElement => classType.element;
}

/// This class gathers and verifies mock targets referenced in `GenerateMocks`
/// annotations.
class _MockTargetGatherer {
  final LibraryElement _entryLib;

  final List<_MockTarget> _mockTargets;

  _MockTargetGatherer._(this._entryLib, this._mockTargets) {
    _checkClassesToMockAreValid();
  }

  /// Searches the top-level elements of [entryLib] for `GenerateMocks`
  /// annotations and creates a [_MockTargetGatherer] with all of the classes
  /// identified as mocking targets.
  factory _MockTargetGatherer(LibraryElement entryLib) {
    final mockTargets = <_MockTarget>{};

    for (final element in entryLib.topLevelElements) {
      // TODO(srawlins): Re-think the idea of multiple @GenerateMocks
      // annotations, on one element or even on different elements in a library.
      for (final annotation in element.metadata) {
        if (annotation == null) continue;
        if (annotation.element is! ConstructorElement) continue;
        final annotationClass = annotation.element.enclosingElement.name;
        // TODO(srawlins): check library as well.
        if (annotationClass == 'GenerateMocks') {
          mockTargets
              .addAll(_mockTargetsFromGenerateMocks(annotation, entryLib));
        }
      }
    }

    return _MockTargetGatherer._(entryLib, mockTargets.toList());
  }

  static Iterable<_MockTarget> _mockTargetsFromGenerateMocks(
      ElementAnnotation annotation, LibraryElement entryLib) {
    final generateMocksValue = annotation.computeConstantValue();
    final classesField = generateMocksValue.getField('classes');
    if (classesField.isNull) {
      throw InvalidMockitoAnnotationException(
          'The GenerateMocks "classes" argument is missing, includes an '
          'unknown type, or includes an extension');
    }
    final mockTargets = <_MockTarget>[];
    for (var objectToMock in classesField.toListValue()) {
      final typeToMock = objectToMock.toTypeValue();
      if (typeToMock == null) {
        throw InvalidMockitoAnnotationException(
            'The "classes" argument includes a non-type: $objectToMock');
      }
      if (typeToMock.isDynamic) {
        throw InvalidMockitoAnnotationException(
            'Mockito cannot mock `dynamic`');
      }
      final type = _determineDartType(typeToMock, entryLib.typeProvider);
      // [type] is `Foo<dynamic>` for generic classes. Switch to declaration,
      // which will yield `Foo<T>`.
      final declarationType =
          (type.element.declaration as ClassElement).thisType;
      final mockName = 'Mock${declarationType.element.name}';
      mockTargets.add(_MockTarget(declarationType, mockName,
          returnNullOnMissingStub: false));
    }
    final customMocksField = generateMocksValue.getField('customMocks');
    if (customMocksField != null && !customMocksField.isNull) {
      for (var mockSpec in customMocksField.toListValue()) {
        final mockSpecType = mockSpec.type;
        assert(mockSpecType.typeArguments.length == 1);
        final typeToMock = mockSpecType.typeArguments.single;
        if (typeToMock.isDynamic) {
          throw InvalidMockitoAnnotationException(
              'Mockito cannot mock `dynamic`; be sure to declare type '
              'arguments on MockSpec(), in @GenerateMocks.');
        }
        var type = _determineDartType(typeToMock, entryLib.typeProvider);
        final mockName = mockSpec.getField('mockName').toSymbolValue() ??
            'Mock${type.element.name}';
        final returnNullOnMissingStub =
            mockSpec.getField('returnNullOnMissingStub').toBoolValue();
        mockTargets.add(_MockTarget(type, mockName,
            returnNullOnMissingStub: returnNullOnMissingStub));
      }
    }
    return mockTargets;
  }

  /// Map the values passed to the GenerateMocks annotation to the classes which
  /// they represent.
  ///
  /// This function is responsible for ensuring that each value is an
  /// appropriate target for mocking. It will throw an
  /// [InvalidMockitoAnnotationException] under various conditions.
  static analyzer.InterfaceType _determineDartType(
      analyzer.DartType typeToMock, TypeProvider typeProvider) {
    if (typeToMock is analyzer.InterfaceType) {
      final elementToMock = typeToMock.element;
      if (elementToMock.isEnum) {
        throw InvalidMockitoAnnotationException(
            'Mockito cannot mock an enum: ${elementToMock.displayName}');
      }
      if (typeProvider.nonSubtypableClasses.contains(elementToMock)) {
        throw InvalidMockitoAnnotationException(
            'Mockito cannot mock a non-subtypable type: '
            '${elementToMock.displayName}. It is illegal to subtype this '
            'type.');
      }
      if (elementToMock.isPrivate) {
        throw InvalidMockitoAnnotationException(
            'Mockito cannot mock a private type: '
            '${elementToMock.displayName}.');
      }
      var typeParameterErrors =
          _checkTypeParameters(elementToMock.typeParameters, elementToMock);
      if (typeParameterErrors.isNotEmpty) {
        var joinedMessages =
            typeParameterErrors.map((m) => '    $m').join('\n');
        throw InvalidMockitoAnnotationException(
            'Mockito cannot generate a valid mock class which implements '
            "'${elementToMock.displayName}' for the following reasons:\n"
            '$joinedMessages');
      }
      return typeToMock;
    }

    var aliasElement = typeToMock.aliasElement;
    if (aliasElement != null) {
      throw InvalidMockitoAnnotationException('Mockito cannot mock a typedef: '
          '${aliasElement.displayName}');
    } else {
      throw InvalidMockitoAnnotationException(
          'Mockito cannot mock a non-class: $typeToMock');
    }
  }

  void _checkClassesToMockAreValid() {
    var classesInEntryLib =
        _entryLib.topLevelElements.whereType<ClassElement>();
    var classNamesToMock = <String, ClassElement>{};
    var uniqueNameSuggestion =
        "use the 'customMocks' argument in @GenerateMocks to specify a unique "
        'name';
    for (final mockTarget in _mockTargets) {
      var name = mockTarget.mockName;
      if (classNamesToMock.containsKey(name)) {
        var firstSource = classNamesToMock[name].source.fullName;
        var secondSource = mockTarget.classElement.source.fullName;
        throw InvalidMockitoAnnotationException(
            'Mockito cannot generate two mocks with the same name: $name (for '
            '${classNamesToMock[name].name} declared in $firstSource, and for '
            '${mockTarget.classElement.name} declared in $secondSource); '
            '$uniqueNameSuggestion.');
      }
      classNamesToMock[name] = mockTarget.classElement;
    }

    classNamesToMock.forEach((name, element) {
      var conflictingClass = classesInEntryLib.firstWhere((c) => c.name == name,
          orElse: () => null);
      if (conflictingClass != null) {
        throw InvalidMockitoAnnotationException(
            'Mockito cannot generate a mock with a name which conflicts with '
            'another class declared in this library: ${conflictingClass.name}; '
            '$uniqueNameSuggestion.');
      }

      var preexistingMock = classesInEntryLib.firstWhere(
          (c) =>
              c.interfaces.map((type) => type.element).contains(element) &&
              _isMockClass(c.supertype),
          orElse: () => null);
      if (preexistingMock != null) {
        throw InvalidMockitoAnnotationException(
            'The GenerateMocks annotation contains a class which appears to '
            'already be mocked inline: ${preexistingMock.name}; '
            '$uniqueNameSuggestion.');
      }

      _checkMethodsToStubAreValid(element);
    });
  }

  /// Throws if any public instance methods of [classElement] are not valid
  /// stubbing candidates.
  ///
  /// A method is not valid for stubbing if:
  /// - It has a private type anywhere in its signature; Mockito cannot override
  ///   such a method.
  /// - It has a non-nullable type variable return type, for example `T m<T>()`.
  ///   Mockito cannot generate dummy return values for unknown types.
  void _checkMethodsToStubAreValid(ClassElement classElement) {
    var className = classElement.name;
    var unstubbableErrorMessages = classElement.methods
        .where((m) => !m.isPrivate && !m.isStatic)
        .expand((m) => _checkFunction(m.type, m))
        .toList();

    if (unstubbableErrorMessages.isNotEmpty) {
      var joinedMessages =
          unstubbableErrorMessages.map((m) => '    $m').join('\n');
      throw InvalidMockitoAnnotationException(
          'Mockito cannot generate a valid mock class which implements '
          "'$className' for the following reasons:\n$joinedMessages");
    }
  }

  /// Checks [function] for properties that would make it un-stubbable.
  ///
  /// Types are checked in the following positions:
  /// - return type
  /// - parameter types
  /// - bounds of type parameters
  /// - type arguments
  List<String> _checkFunction(
      analyzer.FunctionType function, Element enclosingElement) {
    var errorMessages = <String>[];
    var returnType = function.returnType;
    if (returnType is analyzer.InterfaceType) {
      if (returnType.element?.isPrivate ?? false) {
        errorMessages.add(
            '${enclosingElement.fullName} features a private return type, and '
            'cannot be stubbed.');
      }
      errorMessages.addAll(
          _checkTypeArguments(returnType.typeArguments, enclosingElement));
    } else if (returnType is analyzer.FunctionType) {
      errorMessages.addAll(_checkFunction(returnType, enclosingElement));
    } else if (returnType is analyzer.TypeParameterType) {
      if (function.returnType is analyzer.TypeParameterType &&
          _entryLib.typeSystem.isPotentiallyNonNullable(function.returnType)) {
        errorMessages
            .add('${enclosingElement.fullName} features a non-nullable unknown '
                'return type, and cannot be stubbed.');
      }
    }

    for (var parameter in function.parameters) {
      var parameterType = parameter.type;
      if (parameterType is analyzer.InterfaceType) {
        var parameterTypeElement = parameterType.element;
        if (parameterTypeElement?.isPrivate ?? false) {
          // Technically, we can expand the type in the mock to something like
          // `Object?`. However, until there is a decent use case, we will not
          // generate such a mock.
          errorMessages.add(
              '${enclosingElement.fullName} features a private parameter type, '
              "'${parameterTypeElement.name}', and cannot be stubbed.");
        }
        errorMessages.addAll(
            _checkTypeArguments(parameterType.typeArguments, enclosingElement));
      } else if (parameterType is analyzer.FunctionType) {
        errorMessages.addAll(_checkFunction(parameterType, enclosingElement));
      }
    }

    errorMessages
        .addAll(_checkTypeParameters(function.typeFormals, enclosingElement));

    var aliasArguments = function.aliasArguments;
    if (aliasArguments != null) {
      errorMessages
          .addAll(_checkTypeArguments(aliasArguments, enclosingElement));
    }

    return errorMessages;
  }

  /// Checks the bounds of [typeParameters] for properties that would make the
  /// enclosing method un-stubbable.
  static List<String> _checkTypeParameters(
      List<TypeParameterElement> typeParameters, Element enclosingElement) {
    var errorMessages = <String>[];
    for (var element in typeParameters) {
      var typeParameter = element.bound;
      if (typeParameter == null) continue;
      if (typeParameter is analyzer.InterfaceType) {
        if (typeParameter.element?.isPrivate ?? false) {
          errorMessages.add(
              '${enclosingElement.fullName} features a private type parameter '
              'bound, and cannot be stubbed.');
        }
      }
    }
    return errorMessages;
  }

  /// Checks [typeArguments] for properties that would make the enclosing
  /// method un-stubbable.
  ///
  /// See [_checkMethodsToStubAreValid] for what properties make a function
  /// un-stubbable.
  List<String> _checkTypeArguments(
      List<analyzer.DartType> typeArguments, Element enclosingElement) {
    var errorMessages = <String>[];
    for (var typeArgument in typeArguments) {
      if (typeArgument is analyzer.InterfaceType) {
        if (typeArgument.element?.isPrivate ?? false) {
          errorMessages.add(
              '${enclosingElement.fullName} features a private type argument, '
              'and cannot be stubbed.');
        }
      } else if (typeArgument is analyzer.FunctionType) {
        errorMessages.addAll(_checkFunction(typeArgument, enclosingElement));
      }
    }
    return errorMessages;
  }

  /// Return whether [type] is the Mock class declared by mockito.
  bool _isMockClass(analyzer.InterfaceType type) =>
      type.element.name == 'Mock' &&
      type.element.source.fullName.endsWith('lib/src/mock.dart');
}

class _MockLibraryInfo {
  final bool sourceLibIsNonNullable;

  /// The type provider which applies to the source library.
  final TypeProvider typeProvider;

  /// The type system which applies to the source library.
  final TypeSystem typeSystem;

  /// Mock classes to be added to the generated library.
  final mockClasses = <Class>[];

  /// Fake classes to be added to the library.
  ///
  /// A fake class is only generated when it is needed for non-nullable return
  /// values.
  final fakeClasses = <Class>[];

  /// [ClassElement]s which are used in non-nullable return types, for which
  /// fake classes are added to the generated library.
  final fakedClassElements = <ClassElement>[];

  /// A mapping of each necessary [Element] to a URI from which it can be
  /// imported.
  ///
  /// This mapping is generated eagerly so as to avoid any asynchronous
  /// Asset-resolving while building the mock library.
  final Map<Element, String> assetUris;

  /// Build mock classes for [mockTargets].
  _MockLibraryInfo(Iterable<_MockTarget> mockTargets,
      {this.assetUris, LibraryElement entryLib})
      : sourceLibIsNonNullable = entryLib.isNonNullableByDefault,
        typeProvider = entryLib.typeProvider,
        typeSystem = entryLib.typeSystem {
    for (final mockTarget in mockTargets) {
      mockClasses.add(_buildMockClass(mockTarget));
    }
  }

  bool _hasExplicitTypeArguments(analyzer.InterfaceType type) {
    if (type.typeArguments == null) return false;

    // If it appears that one type argument was given, then they all were. This
    // returns the wrong result when the type arguments given are all `dynamic`,
    // or are each equal to the bound of the corresponding type parameter. There
    // may not be a way to get around this.
    for (var i = 0; i < type.typeArguments.length; i++) {
      var typeArgument = type.typeArguments[i];
      // If [typeArgument] is a type parameter, this indicates that no type
      // arguments were passed. This likely came from the 'classes' argument of
      // GenerateMocks, and [type] is the declaration type (`Foo<T>` vs
      // `Foo<dynamic>`).
      if (typeArgument is analyzer.TypeParameterType) return false;

      // If [type] was given to @GenerateMocks as a Type, and no explicit type
      // argument is given, [typeArgument] is `dynamic` (_not_ the bound, as one
      // might think). We determine that an explicit type argument was given if
      // it is not `dynamic`.
      if (typeArgument.isDynamic) continue;

      // If, on the other hand, [type] was given to @GenerateMock as a type
      // argument to `Of()`, and no type argument is given, [typeArgument] is
      // the bound of the corresponding type paramter (dynamic or otherwise). We
      // determine that an explicit type argument was given if [typeArgument] is
      // not [bound].
      var bound =
          type.element.typeParameters[i].bound ?? typeProvider.dynamicType;
      if (!typeArgument.isDynamic && typeArgument != bound) return true;
    }
    return false;
  }

  Class _buildMockClass(_MockTarget mockTarget) {
    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 = refer('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 (_hasExplicitTypeArguments(typeToMock)) {
        // [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(refer(typeArgument.element.name));
        }
      } 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;
      }
      cBuilder.methods.addAll(fieldOverrides(typeToMock, {}));
      cBuilder.methods.addAll(methodOverrides(typeToMock, {}));
    });
  }

  /// Yields all of the field overrides required for [type].
  ///
  /// This includes fields of supertypes and mixed in types. [overriddenFields]
  /// is used to track which fields have already been yielded.
  ///
  /// Only public instance fields which have either a potentially non-nullable
  /// return type (for getters) or a parameter with a potentially non-nullable
  /// type (for setters) are yielded.
  Iterable<Method> fieldOverrides(
      analyzer.InterfaceType type, Set<String> overriddenFields) sync* {
    for (final accessor in type.accessors) {
      if (accessor.isPrivate || accessor.isStatic) {
        continue;
      }
      if (overriddenFields.contains(accessor.name)) {
        continue;
      }
      overriddenFields.add(accessor.name);
      if (accessor.isGetter && _returnTypeIsNonNullable(accessor)) {
        yield Method((mBuilder) => _buildOverridingGetter(mBuilder, accessor));
      }
      if (accessor.isSetter) {
        yield Method((mBuilder) => _buildOverridingSetter(mBuilder, accessor));
      }
    }
    if (type.mixins != null) {
      for (var mixin in type.mixins) {
        yield* fieldOverrides(mixin, overriddenFields);
      }
    }
    var superclass = type.superclass;
    if (superclass != null && !superclass.isDartCoreObject) {
      yield* fieldOverrides(superclass, overriddenFields);
    }
  }

  /// Yields all of the method overrides required for [type].
  ///
  /// This includes methods of supertypes and mixed in types.
  /// [overriddenMethods] is used to track which methods have already been
  /// yielded.
  ///
  /// Only public instance methods which have either a potentially non-nullable
  /// return type or a parameter with a potentially non-nullable type are
  /// yielded.
  Iterable<Method> methodOverrides(
      analyzer.InterfaceType type, Set<String> overriddenMethods) sync* {
    for (final method in type.methods) {
      if (method.isPrivate || method.isStatic) {
        continue;
      }
      var methodName = method.name;
      if (overriddenMethods.contains(methodName)) {
        continue;
      }
      overriddenMethods.add(methodName);
      if (methodName == 'noSuchMethod') {
        continue;
      }
      if (_returnTypeIsNonNullable(method) ||
          _hasNonNullableParameter(method) ||
          _needsOverrideForVoidStub(method)) {
        yield Method((mBuilder) => _buildOverridingMethod(mBuilder, method,
            className: type.getDisplayString(withNullability: true)));
      }
    }
    if (type.mixins != null) {
      for (var mixin in type.mixins) {
        yield* methodOverrides(mixin, overriddenMethods);
      }
    }
    var superclass = type.superclass;
    if (superclass != null && !superclass.isDartCoreObject) {
      yield* methodOverrides(superclass, overriddenMethods);
    }
  }

  /// The default behavior of mocks is to return null for unstubbed methods. To
  /// use the new behavior of throwing an error, we must explicitly call
  /// `throwOnMissingStub`.
  Constructor get _constructorWithThrowOnMissingStub =>
      Constructor((cBuilder) => cBuilder.body =
          refer('throwOnMissingStub', 'package:mockito/mockito.dart')
              .call([refer('this').expression]).statement);

  bool _returnTypeIsNonNullable(ExecutableElement method) =>
      typeSystem.isPotentiallyNonNullable(method.returnType);

  bool _needsOverrideForVoidStub(ExecutableElement method) =>
      method.returnType.isVoid || method.returnType.isFutureOfVoid;

  // Returns whether [method] has at least one parameter whose type is
  // potentially non-nullable.
  //
  // A parameter whose type uses a type variable may be non-nullable on certain
  // instances. For example:
  //
  //     class C<T> {
  //       void m(T a) {}
  //     }
  //     final c1 = C<int?>(); // m's parameter's type is nullable.
  //     final c2 = C<int>(); // m's parameter's type is non-nullable.
  bool _hasNonNullableParameter(ExecutableElement method) =>
      method.parameters.any((p) => typeSystem.isPotentiallyNonNullable(p.type));

  /// Build a method which overrides [method], with all non-nullable
  /// parameter types widened to be nullable.
  ///
  /// This new method just calls `super.noSuchMethod`, optionally passing a
  /// return value for methods with a non-nullable return type.
  void _buildOverridingMethod(MethodBuilder builder, MethodElement method,
      {@required String className}) {
    var name = method.displayName;
    if (method.isOperator) name = 'operator$name';
    builder
      ..name = name
      ..annotations.addAll([refer('override')])
      ..returns = _typeReference(method.returnType);

    if (method.typeParameters != null) {
      builder.types.addAll(method.typeParameters.map(_typeParameterReference));
    }

    // These two variables store the arguments that will be passed to the
    // [Invocation] built for `noSuchMethod`.
    final invocationPositionalArgs = <Expression>[];
    final invocationNamedArgs = <Expression, Expression>{};

    for (final parameter in method.parameters) {
      if (parameter.isRequiredPositional) {
        builder.requiredParameters
            .add(_matchingParameter(parameter, forceNullable: true));
        invocationPositionalArgs.add(refer(parameter.displayName));
      } else if (parameter.isOptionalPositional) {
        builder.optionalParameters
            .add(_matchingParameter(parameter, forceNullable: true));
        invocationPositionalArgs.add(refer(parameter.displayName));
      } else if (parameter.isNamed) {
        builder.optionalParameters
            .add(_matchingParameter(parameter, forceNullable: true));
        invocationNamedArgs[refer('#${parameter.displayName}')] =
            refer(parameter.displayName);
      }
    }

    final invocation = refer('Invocation').property('method').call([
      refer('#${method.displayName}'),
      literalList(invocationPositionalArgs),
      if (invocationNamedArgs.isNotEmpty) literalMap(invocationNamedArgs),
    ]);

    Expression returnValueForMissingStub;
    if (method.returnType.isVoid) {
      returnValueForMissingStub = refer('null');
    } else if (method.returnType.isFutureOfVoid) {
      returnValueForMissingStub = refer('Future').property('value').call([]);
    }
    final namedArgs = {
      if (_returnTypeIsNonNullable(method))
        'returnValue': _dummyValue(method.returnType),
      if (returnValueForMissingStub != null)
        'returnValueForMissingStub': returnValueForMissingStub,
    };

    var superNoSuchMethod =
        refer('super').property('noSuchMethod').call([invocation], namedArgs);
    if (!method.returnType.isVoid && !method.returnType.isDynamic) {
      superNoSuchMethod =
          superNoSuchMethod.asA(_typeReference(method.returnType));
    }

    builder
      ..lambda = true
      ..body = superNoSuchMethod.code;
  }

  Expression _dummyValue(analyzer.DartType type) {
    if (type is analyzer.FunctionType) {
      return _dummyFunctionValue(type);
    }

    if (type is! analyzer.InterfaceType) {
      // TODO(srawlins): This case is not known.
      return literalNull;
    }

    var interfaceType = type as analyzer.InterfaceType;
    var typeArguments = interfaceType.typeArguments;
    if (interfaceType.isDartCoreBool) {
      return literalFalse;
    } else if (interfaceType.isDartCoreDouble) {
      return literalNum(0.0);
    } else if (interfaceType.isDartAsyncFuture ||
        interfaceType.isDartAsyncFutureOr) {
      var typeArgument = typeArguments.first;
      return refer('Future')
          .property('value')
          .call([_dummyValue(typeArgument)]);
    } else if (interfaceType.isDartCoreInt) {
      return literalNum(0);
    } else if (interfaceType.isDartCoreIterable) {
      return literalList([]);
    } else if (interfaceType.isDartCoreList) {
      assert(typeArguments.length == 1);
      var elementType = _typeReference(typeArguments[0]);
      return literalList([], elementType);
    } else if (interfaceType.isDartCoreMap) {
      assert(typeArguments.length == 2);
      var keyType = _typeReference(typeArguments[0]);
      var valueType = _typeReference(typeArguments[1]);
      return literalMap({}, keyType, valueType);
    } else if (interfaceType.isDartCoreNum) {
      return literalNum(0);
    } else if (interfaceType.isDartCoreSet) {
      assert(typeArguments.length == 1);
      var elementType = _typeReference(typeArguments[0]);
      return literalSet({}, elementType);
    } else if (interfaceType.element?.declaration ==
        typeProvider.streamElement) {
      assert(typeArguments.length == 1);
      var elementType = _typeReference(typeArguments[0]);
      return TypeReference((b) {
        b
          ..symbol = 'Stream'
          ..types.add(elementType);
      }).property('empty').call([]);
    } else if (interfaceType.isDartCoreString) {
      return literalString('');
    }

    // This class is unknown; we must likely generate a fake class, and return
    // an instance here.
    return _dummyValueImplementing(type as analyzer.InterfaceType);
  }

  Expression _dummyFunctionValue(analyzer.FunctionType type) {
    return Method((b) {
      // The positional parameters in a FunctionType have no names. This
      // counter lets us create unique dummy names.
      var counter = 0;
      if (type.typeFormals != null) {
        b.types.addAll(type.typeFormals.map(_typeParameterReference));
      }
      for (final parameter in type.parameters) {
        if (parameter.isRequiredPositional) {
          b.requiredParameters
              .add(_matchingParameter(parameter, defaultName: '__p$counter'));
          counter++;
        } else if (parameter.isOptionalPositional) {
          b.optionalParameters
              .add(_matchingParameter(parameter, defaultName: '__p$counter'));
          counter++;
        } else if (parameter.isNamed) {
          b.optionalParameters.add(_matchingParameter(parameter));
        }
      }
      if (type.returnType.isVoid) {
        b.body = Code('');
      } else {
        b.body = _dummyValue(type.returnType).code;
      }
    }).genericClosure;
  }

  Expression _dummyValueImplementing(analyzer.InterfaceType dartType) {
    // For each type parameter on [dartType], the Mock class needs a type
    // parameter with same type variables, and a mirrored type argument for the
    // "implements" clause.
    var typeParameters = <Reference>[];
    var elementToFake = dartType.element;
    if (elementToFake.isEnum) {
      return _typeReference(dartType).property(
          elementToFake.fields.firstWhere((f) => f.isEnumConstant).name);
    } else {
      // There is a potential for these names to collide. If one mock class
      // requires a fake for a certain Foo, and another mock class requires a
      // fake for a different Foo, they will collide.
      var fakeName = '_Fake${elementToFake.name}';
      // Only make one fake class for each class that needs to be faked.
      if (!fakedClassElements.contains(elementToFake)) {
        fakeClasses.add(Class((cBuilder) {
          cBuilder
            ..name = fakeName
            ..extend = refer('Fake', 'package:mockito/mockito.dart');
          if (elementToFake.typeParameters != null) {
            for (var typeParameter in elementToFake.typeParameters) {
              cBuilder.types.add(_typeParameterReference(typeParameter));
              typeParameters.add(refer(typeParameter.name));
            }
          }
          cBuilder.implements.add(TypeReference((b) {
            b
              ..symbol = elementToFake.name
              ..url = _typeImport(elementToFake)
              ..types.addAll(typeParameters);
          }));
        }));
        fakedClassElements.add(elementToFake);
      }
      var typeArguments = dartType.typeArguments;
      return TypeReference((b) {
        b
          ..symbol = fakeName
          ..types.addAll(typeArguments.map(_typeReference));
      }).newInstance([]);
    }
  }

  /// Returns a [Parameter] which matches [parameter].
  ///
  /// If [parameter] is unnamed (like a positional parameter in a function
  /// type), a [defaultName] can be passed as the name.
  ///
  /// If the type needs to be nullable, rather than matching the nullability of
  /// [parameter], use [forceNullable].
  Parameter _matchingParameter(ParameterElement parameter,
      {String defaultName, bool forceNullable = false}) {
    var name = parameter.name?.isEmpty ?? false ? defaultName : parameter.name;
    return Parameter((pBuilder) {
      pBuilder
        ..name = name
        ..type = _typeReference(parameter.type, forceNullable: forceNullable);
      if (parameter.isNamed) pBuilder.named = true;
      if (parameter.defaultValueCode != null) {
        try {
          pBuilder.defaultTo =
              _expressionFromDartObject(parameter.computeConstantValue()).code;
        } on _ReviveException catch (e) {
          final method = parameter.enclosingElement;
          final clazz = method.enclosingElement;
          throw InvalidMockitoAnnotationException(
              'Mockito cannot generate a valid stub for method '
              "'${clazz.displayName}.${method.displayName}'; parameter "
              "'${parameter.displayName}' causes a problem: ${e.message}");
        }
      }
    });
  }

  /// Creates a code_builder [Expression] from [object], a constant object from
  /// analyzer.
  ///
  /// This is very similar to Angular's revive code, in
  /// angular_compiler/analyzer/di/injector.dart.
  Expression _expressionFromDartObject(DartObject object) {
    final constant = ConstantReader(object);
    if (constant.isNull) {
      return literalNull;
    } else if (constant.isBool) {
      return literalBool(constant.boolValue);
    } else if (constant.isDouble) {
      return literalNum(constant.doubleValue);
    } else if (constant.isInt) {
      return literalNum(constant.intValue);
    } else if (constant.isString) {
      return literalString(constant.stringValue, raw: true);
    } else if (constant.isList) {
      return literalConstList([
        for (var element in constant.listValue)
          _expressionFromDartObject(element)
      ]);
    } else if (constant.isMap) {
      return literalConstMap({
        for (var pair in constant.mapValue.entries)
          _expressionFromDartObject(pair.key):
              _expressionFromDartObject(pair.value)
      });
    } else if (constant.isSet) {
      return literalConstSet({
        for (var element in constant.setValue)
          _expressionFromDartObject(element)
      });
    } else if (constant.isType) {
      // TODO(srawlins): It seems like this might be revivable, but Angular
      // does not revive Types; we should investigate this if users request it.
      var type = object.toTypeValue();
      var typeStr = type.getDisplayString(withNullability: false);
      throw _ReviveException('default value is a Type: $typeStr.');
    } else {
      // If [constant] is not null, a literal, or a type, then it must be an
      // object constructed with `const`. Revive it.
      var revivable = constant.revive();
      if (revivable.isPrivate) {
        final privateReference = revivable.accessor?.isNotEmpty == true
            ? '${revivable.source}::${revivable.accessor}'
            : '${revivable.source}';
        throw _ReviveException(
            'default value has a private type: $privateReference.');
      }
      if (object.toFunctionValue() != null) {
        // A top-level function, like `void f() {}` must be referenced by its
        // identifier, rather than a revived value.
        var element = object.toFunctionValue();
        return refer(revivable.accessor, _typeImport(element));
      } else if (revivable.source.fragment.isEmpty) {
        // We can create this invocation by referring to a const field or
        // top-level variable.
        return refer(revivable.accessor, _typeImport(object.type.element));
      }

      final name = revivable.source.fragment;
      final positionalArgs = [
        for (var argument in revivable.positionalArguments)
          _expressionFromDartObject(argument)
      ];
      final namedArgs = {
        for (var pair in revivable.namedArguments.entries)
          pair.key: _expressionFromDartObject(pair.value)
      };
      final type = refer(name, _typeImport(object.type.element));
      if (revivable.accessor.isNotEmpty) {
        return type.constInstanceNamed(
          revivable.accessor,
          positionalArgs,
          namedArgs,
          // No type arguments. See
          // https://github.com/dart-lang/source_gen/issues/478.
        );
      }
      return type.constInstance(positionalArgs, namedArgs);
    }
  }

  /// Build a getter which overrides [getter].
  ///
  /// This new method just calls `super.noSuchMethod`, optionally passing a
  /// return value for non-nullable getters.
  void _buildOverridingGetter(
      MethodBuilder builder, PropertyAccessorElement getter) {
    builder
      ..name = getter.displayName
      ..annotations.addAll([refer('override')])
      ..type = MethodType.getter
      ..returns = _typeReference(getter.returnType);

    final invocation = refer('Invocation').property('getter').call([
      refer('#${getter.displayName}'),
    ]);
    final namedArgs = {'returnValue': _dummyValue(getter.returnType)};
    var superNoSuchMethod =
        refer('super').property('noSuchMethod').call([invocation], namedArgs);
    if (!getter.returnType.isVoid && !getter.returnType.isDynamic) {
      superNoSuchMethod =
          superNoSuchMethod.asA(_typeReference(getter.returnType));
    }

    builder
      ..lambda = true
      ..body = superNoSuchMethod.code;
  }

  /// Build a setter which overrides [setter], widening the single parameter
  /// type to be nullable if it is non-nullable.
  ///
  /// This new setter just calls `super.noSuchMethod`.
  void _buildOverridingSetter(
      MethodBuilder builder, PropertyAccessorElement setter) {
    builder
      ..name = setter.displayName
      ..annotations.addAll([refer('override')])
      ..type = MethodType.setter;

    Expression invocationPositionalArg;
    assert(setter.parameters.length == 1);
    final parameter = setter.parameters.single;
    if (parameter.isRequiredPositional) {
      builder.requiredParameters.add(Parameter((pBuilder) => pBuilder
        ..name = parameter.displayName
        ..type = _typeReference(parameter.type, forceNullable: true)));
      invocationPositionalArg = refer(parameter.displayName);
    }

    final invocation = refer('Invocation').property('setter').call([
      refer('#${setter.displayName}'),
      invocationPositionalArg,
    ]);
    final returnNoSuchMethod = refer('super')
        .property('noSuchMethod')
        .call([invocation], {'returnValueForMissingStub': refer('null')});

    builder.body = returnNoSuchMethod.code;
  }

  /// Create a reference for [typeParameter], properly referencing all types
  /// in bounds.
  TypeReference _typeParameterReference(TypeParameterElement typeParameter) {
    return TypeReference((b) {
      b.symbol = typeParameter.name;
      if (typeParameter.bound != null) {
        b.bound = _typeReference(typeParameter.bound);
      }
    });
  }

  /// Create a reference for [type], properly referencing all attached types.
  ///
  /// If the type needs to be nullable, rather than matching the nullability of
  /// [type], use [forceNullable].
  ///
  /// This creates proper references for:
  /// * InterfaceTypes (classes, generic classes),
  /// * FunctionType parameters (like `void callback(int i)`),
  /// * type aliases (typedefs), both new- and old-style,
  /// * enums,
  /// * type variables.
  // TODO(srawlins): Contribute this back to a common location, like
  // package:source_gen?
  Reference _typeReference(analyzer.DartType type,
      {bool forceNullable = false}) {
    if (type is analyzer.InterfaceType) {
      return TypeReference((b) {
        b
          ..symbol = type.element.name
          ..isNullable = forceNullable || typeSystem.isPotentiallyNullable(type)
          ..url = _typeImport(type.element)
          ..types.addAll(type.typeArguments.map(_typeReference));
      });
    } else if (type is analyzer.FunctionType) {
      var element = type.aliasElement;
      if (element == null) {
        // [type] represents a FunctionTypedFormalParameter.
        return FunctionType((b) {
          b
            ..isNullable =
                forceNullable || typeSystem.isPotentiallyNullable(type)
            ..returnType = _typeReference(type.returnType)
            ..requiredParameters
                .addAll(type.normalParameterTypes.map(_typeReference))
            ..optionalParameters
                .addAll(type.optionalParameterTypes.map(_typeReference));
          for (var parameter in type.namedParameterTypes.entries) {
            b.namedParameters[parameter.key] = _typeReference(parameter.value);
          }
          if (type.typeFormals != null) {
            b.types.addAll(type.typeFormals.map(_typeParameterReference));
          }
        });
      }
      return TypeReference((b) {
        b
          ..symbol = element.name
          ..url = _typeImport(element)
          ..isNullable = forceNullable || typeSystem.isNullable(type);
        for (var typeArgument in type.aliasArguments) {
          b.types.add(_typeReference(typeArgument));
        }
      });
    } else if (type is analyzer.TypeParameterType) {
      return TypeReference((b) {
        b
          ..symbol = type.element.name
          ..isNullable = forceNullable || typeSystem.isNullable(type);
      });
    } else {
      return refer(
        type.getDisplayString(withNullability: false),
        _typeImport(type.element),
      );
    }
  }

  /// Returns the import URL for [element].
  ///
  /// For some types, like `dynamic` and type variables, this may return null.
  String _typeImport(Element element) {
    // For type variables, no import needed.
    if (element is TypeParameterElement) return null;

    // For types like `dynamic`, return null; no import needed.
    if (element?.library == null) return null;

    assert(assetUris.containsKey(element),
        () => 'An element, "$element", is missing from the asset URI mapping');

    return assetUris[element];
  }
}

/// An exception thrown when reviving a potentially deep value in a constant.
///
/// This exception should always be caught within this library. An
/// [InvalidMockitoAnnotationException] can be presented to the user after
/// catching this exception.
class _ReviveException implements Exception {
  final String message;

  _ReviveException(this.message);
}

/// An exception which is thrown when Mockito encounters an invalid annotation.
class InvalidMockitoAnnotationException implements Exception {
  final String message;

  InvalidMockitoAnnotationException(this.message);

  @override
  String toString() => 'Invalid @GenerateMocks annotation: $message';
}

/// A [MockBuilder] instance for use by `build.yaml`.
Builder buildMocks(BuilderOptions options) => MockBuilder();

extension on Element {
  /// Returns the "full name" of a class or method element.
  String get fullName {
    if (this is ClassElement) {
      return "The class '$name'";
    } else if (this is MethodElement) {
      var className = enclosingElement.name;
      return "The method '$className.$name'";
    } else {
      return 'unknown element';
    }
  }
}

extension on analyzer.DartType {
  /// Returns whether this type is `Future<void>` or `Future<void>?`.
  bool get isFutureOfVoid =>
      isDartAsyncFuture &&
      (this as analyzer.InterfaceType).typeArguments.first.isVoid;
}
