// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:kernel/ast.dart' hide Combinator, MapLiteralEntry;
import 'package:kernel/class_hierarchy.dart'
    show ClassHierarchyBase, ClassHierarchyMembers;
import 'package:kernel/src/bounds_checks.dart'
    show
        TypeArgumentIssue,
        findTypeArgumentIssues,
        findTypeArgumentIssuesForInvocation,
        getGenericTypeName,
        hasGenericFunctionTypeAsTypeArgument;
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart' show TypeEnvironment;

import '../api_prototype/experimental_flags.dart';
import '../base/compiler_context.dart';
import '../base/messages.dart';
import '../base/uri_offset.dart';
import '../builder/formal_parameter_builder.dart';
import '../kernel/internal_ast.dart';
import 'source_library_builder.dart';

extension CheckHelper on ProblemReporting {
  InvalidExpression buildProblem({
    required CompilerContext compilerContext,
    required Message message,
    required Uri fileUri,
    required int fileOffset,
    required int length,
    List<LocatedMessage>? context,
    bool errorHasBeenReported = false,
    Expression? expression,
  }) {
    if (!errorHasBeenReported) {
      addProblem(
        message,
        fileOffset,
        length,
        fileUri,
        wasHandled: true,
        context: context,
      );
    }
    String text = compilerContext
        .format(
          message.withLocation(fileUri, fileOffset, length),
          CfeSeverity.error,
        )
        .plain;
    return new InvalidExpression(text, expression)..fileOffset = fileOffset;
  }

  Expression buildProblemWithContextFromMember({
    required CompilerContext compilerContext,
    required String name,
    required Member member,
    required LocatedMessage message,
    required Uri fileUri,
  }) {
    List<LocatedMessage>? context;
    Location? location = member.location;
    if (location != null) {
      Uri uri = location.file;
      int offset = member.fileOffset;
      Message contextMessage;
      int length = noLength;
      if (member is Constructor && member.isSynthetic) {
        offset = member.enclosingClass.fileOffset;
        contextMessage = codeCandidateFoundIsDefaultConstructor
            .withArgumentsOld(member.enclosingClass.name);
      } else {
        if (member is Constructor) {
          if (member.name.text == '') {
            length = member.enclosingClass.name.length;
          } else {
            // Assume no spaces around the dot. Not perfect, but probably the
            // best we can do with the information available.
            length = member.enclosingClass.name.length + 1 + name.length;
          }
        } else {
          length = name.length;
        }
        contextMessage = codeCandidateFound;
      }
      context = [contextMessage.withLocation(uri, offset, length)];
    }
    return buildProblem(
      compilerContext: compilerContext,
      message: message.messageObject,
      fileUri: fileUri,
      fileOffset: message.charOffset,
      length: message.length,
      context: context,
    );
  }

  Expression buildProblemFromLocatedMessage({
    required CompilerContext compilerContext,
    required LocatedMessage message,
  }) {
    return buildProblem(
      compilerContext: compilerContext,
      message: message.messageObject,
      fileUri: message.uri!,
      fileOffset: message.charOffset,
      length: message.length,
    );
  }

  LocatedMessage? checkArgumentsForFunction({
    required FunctionNode function,
    required Arguments arguments,
    required int fileOffset,
    required Uri fileUri,
    required List<TypeParameter> typeParameters,
    Extension? extension,
  }) {
    int typeParameterCount = typeParameters.length;
    int requiredParameterCount = function.requiredParameterCount;
    int positionalParameterCount = function.positionalParameters.length;
    int positionalArgumentsCount = arguments.positional.length;
    if (extension != null) {
      // Extension member invocations have additional synthetic parameter for
      // `this`.
      --requiredParameterCount;
      --positionalParameterCount;
      typeParameterCount -= extension.typeParameters.length;
    }
    if (positionalArgumentsCount < requiredParameterCount) {
      return codeTooFewArguments
          .withArgumentsOld(requiredParameterCount, positionalArgumentsCount)
          .withLocation(fileUri, arguments.fileOffset, noLength);
    }
    if (positionalArgumentsCount > positionalParameterCount) {
      return codeTooManyArguments
          .withArgumentsOld(positionalParameterCount, positionalArgumentsCount)
          .withLocation(fileUri, arguments.fileOffset, noLength);
    }
    List<NamedExpression> named = arguments.named;
    if (named.isNotEmpty) {
      Set<String?> parameterNames = new Set.of(
        function.namedParameters.map((a) => a.name),
      );
      for (int i = 0; i < named.length; i++) {
        NamedExpression argument = named[i];
        if (!parameterNames.contains(argument.name)) {
          return codeNoSuchNamedParameter
              .withArgumentsOld(argument.name)
              .withLocation(fileUri, argument.fileOffset, argument.name.length);
        }
      }
    }
    if (function.namedParameters.isNotEmpty) {
      Set<String> argumentNames = new Set.of(named.map((a) => a.name));
      for (int i = 0; i < function.namedParameters.length; i++) {
        VariableDeclaration parameter = function.namedParameters[i];
        if (parameter.isRequired && !argumentNames.contains(parameter.name)) {
          return codeValueForRequiredParameterNotProvidedError
              .withArgumentsOld(parameter.name!)
              .withLocation(fileUri, arguments.fileOffset, noLength);
        }
      }
    }

    List<DartType> types = arguments.types;
    if (typeParameterCount != types.length) {
      if (types.length == 0) {
        // Expected `typeParameters.length` type arguments, but none given, so
        // we use type inference.
      } else {
        // A wrong (non-zero) amount of type arguments given. That's an error.
        // TODO(jensj): Position should be on type arguments instead.
        return codeTypeArgumentMismatch
            .withArgumentsOld(typeParameterCount)
            .withLocation(fileUri, fileOffset, noLength);
      }
    }

    return null;
  }

  LocatedMessage? checkArgumentsForType({
    required FunctionType function,
    required Arguments arguments,
    required Uri fileUri,
    required int fileOffset,
  }) {
    int requiredPositionalParameterCountToReport =
        function.requiredParameterCount;
    int positionalParameterCountToReport = function.positionalParameters.length;
    int positionalArgumentCountToReport = arguments.positional.length;
    if (arguments.positional.length < function.requiredParameterCount) {
      return codeTooFewArguments
          .withArgumentsOld(
            requiredPositionalParameterCountToReport,
            positionalArgumentCountToReport,
          )
          .withLocation(fileUri, arguments.fileOffset, noLength);
    }
    if (arguments.positional.length > function.positionalParameters.length) {
      return codeTooManyArguments
          .withArgumentsOld(
            positionalParameterCountToReport,
            positionalArgumentCountToReport,
          )
          .withLocation(fileUri, arguments.fileOffset, noLength);
    }
    List<NamedExpression> named = arguments.named;
    if (named.isNotEmpty) {
      Set<String> names = new Set.of(
        function.namedParameters.map((a) => a.name),
      );
      for (int i = 0; i < named.length; i++) {
        NamedExpression argument = named[i];
        if (!names.contains(argument.name)) {
          return codeNoSuchNamedParameter
              .withArgumentsOld(argument.name)
              .withLocation(fileUri, argument.fileOffset, argument.name.length);
        }
      }
    }
    if (function.namedParameters.isNotEmpty) {
      Set<String> argumentNames = new Set.of(named.map((a) => a.name));
      for (int i = 0; i < function.namedParameters.length; i++) {
        NamedType parameter = function.namedParameters[i];
        if (parameter.isRequired && !argumentNames.contains(parameter.name)) {
          return codeValueForRequiredParameterNotProvidedError
              .withArgumentsOld(parameter.name)
              .withLocation(fileUri, arguments.fileOffset, noLength);
        }
      }
    }
    List<Object> types = arguments.types;
    List<StructuralParameter> typeParameters = function.typeParameters;
    if (typeParameters.length != types.length && types.length != 0) {
      // A wrong (non-zero) amount of type arguments given. That's an error.
      // TODO(jensj): Position should be on type arguments instead.
      return codeTypeArgumentMismatch
          .withArgumentsOld(typeParameters.length)
          .withLocation(fileUri, fileOffset, noLength);
    }

    return null;
  }

  void checkAsyncReturnType({
    required SourceLibraryBuilder libraryBuilder,
    required TypeEnvironment typeEnvironment,
    required AsyncMarker asyncModifier,
    required DartType returnType,
    required Uri fileUri,
    required int fileOffset,
    required int length,
  }) {
    // For async, async*, and sync* functions with declared return types, we
    // need to determine whether those types are valid.
    // We use the same trick in each case below. For example to decide whether
    // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
    // transitivity of the subtyping relation because Future<Bot> <: Future<T>
    // for every T.

    // We use [problem == null] to signal success.
    Message? problem;
    switch (asyncModifier) {
      case AsyncMarker.Async:
        DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
        if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType)) {
          problem = codeIllegalAsyncReturnType;
        }
        break;

      case AsyncMarker.AsyncStar:
        DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
        if (returnType is VoidType) {
          problem = codeIllegalAsyncGeneratorVoidReturnType;
        } else if (!typeEnvironment.isSubtypeOf(streamBottomType, returnType)) {
          problem = codeIllegalAsyncGeneratorReturnType;
        }
        break;

      case AsyncMarker.SyncStar:
        DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
        if (returnType is VoidType) {
          problem = codeIllegalSyncGeneratorVoidReturnType;
        } else if (!typeEnvironment.isSubtypeOf(
          iterableBottomType,
          returnType,
        )) {
          problem = codeIllegalSyncGeneratorReturnType;
        }
        break;

      case AsyncMarker.Sync:
        break; // skip
    }

    if (problem != null) {
      // TODO(hillerstrom): once types get annotated with location
      // information, we can improve the quality of the error message by
      // using the offset of [returnType] (and the length of its name).
      addProblem(problem, fileOffset, length, fileUri);
    }
  }

  void checkBoundsInConstructorInvocation({
    required LibraryFeatures libraryFeatures,
    required Constructor constructor,
    required List<DartType> typeArguments,
    required TypeEnvironment typeEnvironment,
    required Uri fileUri,
    required int fileOffset,
    bool inferred = false,
  }) {
    if (typeArguments.isEmpty) return;
    Class klass = constructor.enclosingClass;
    DartType constructedType = new InterfaceType(
      klass,
      klass.enclosingLibrary.nonNullable,
      typeArguments,
    );
    checkBoundsInType(
      libraryFeatures: libraryFeatures,
      type: constructedType,
      typeEnvironment: typeEnvironment,
      fileUri: fileUri,
      fileOffset: fileOffset,
      inferred: inferred,
      allowSuperBounded: false,
    );
  }

  void checkBoundsInFactoryInvocation({
    required LibraryFeatures libraryFeatures,
    required Procedure factory,
    required List<DartType> typeArguments,
    required TypeEnvironment typeEnvironment,
    required Uri fileUri,
    required int fileOffset,
    bool inferred = false,
  }) {
    if (typeArguments.isEmpty) return;
    assert(factory.isFactory || factory.isExtensionTypeMember);
    DartType constructedType = Substitution.fromPairs(
      factory.function.typeParameters,
      typeArguments,
    ).substituteType(factory.function.returnType);
    checkBoundsInType(
      libraryFeatures: libraryFeatures,
      type: constructedType,
      typeEnvironment: typeEnvironment,
      fileUri: fileUri,
      fileOffset: fileOffset,
      inferred: inferred,
      allowSuperBounded: false,
    );
  }

  void checkBoundsInFunctionInvocation({
    required ProblemReportingHelper problemReportingHelper,
    required LibraryFeatures libraryFeatures,
    required TypeEnvironment typeEnvironment,
    required FunctionType functionType,
    required String? localName,
    required ArgumentsImpl arguments,
    required Uri fileUri,
    required int fileOffset,
  }) {
    if (arguments.types.isEmpty) return;

    if (functionType.typeParameters.length != arguments.types.length) {
      assert(
        problemReportingHelper.assertProblemReportedElsewhere(
          "SourceLibraryBuilder.checkBoundsInFunctionInvocation: "
          "the numbers of type parameters and type arguments don't match.",
          expectedPhase: CompilationPhaseForProblemReporting.outline,
        ),
      );
      return;
    }
    final DartType bottomType = const NeverType.nonNullable();
    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
      getFreshTypeParametersFromStructuralParameters(
        functionType.typeParameters,
      ).freshTypeParameters,
      arguments.types,
      typeEnvironment,
      bottomType,
      areGenericArgumentsAllowed: libraryFeatures.genericMetadata.isEnabled,
    );
    _reportTypeArgumentIssues(
      issues,
      fileUri,
      fileOffset,
      inferred: !arguments.hasExplicitTypeArguments,
      // TODO(johnniwinther): Special-case messaging on function type
      //  invocation to avoid reference to 'call' and use the function type
      //  instead.
      targetName: localName ?? 'call',
    );
  }

  void checkBoundsInInstantiation({
    required ProblemReportingHelper problemReportingHelper,
    required LibraryFeatures libraryFeatures,
    required TypeEnvironment typeEnvironment,
    required FunctionType functionType,
    required List<DartType> typeArguments,
    required Uri fileUri,
    required int fileOffset,
    required bool inferred,
  }) {
    if (typeArguments.isEmpty) return;

    if (functionType.typeParameters.length != typeArguments.length) {
      // Coverage-ignore-block(suite): Not run.
      assert(
        problemReportingHelper.assertProblemReportedElsewhere(
          "SourceLibraryBuilder.checkBoundsInInstantiation: "
          "the numbers of type parameters and type arguments don't match.",
          expectedPhase: CompilationPhaseForProblemReporting.outline,
        ),
      );
      return;
    }
    final DartType bottomType = const NeverType.nonNullable();
    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
      getFreshTypeParametersFromStructuralParameters(
        functionType.typeParameters,
      ).freshTypeParameters,
      typeArguments,
      typeEnvironment,
      bottomType,
      areGenericArgumentsAllowed: libraryFeatures.genericMetadata.isEnabled,
    );
    _reportTypeArgumentIssues(
      issues,
      fileUri,
      fileOffset,
      targetReceiver: functionType,
      inferred: inferred,
    );
  }

  void checkBoundsInMethodInvocation({
    required ProblemReportingHelper problemReportingHelper,
    required LibraryFeatures libraryFeatures,
    required DartType receiverType,
    required TypeEnvironment typeEnvironment,
    required ClassHierarchyBase classHierarchy,
    required ClassHierarchyMembers membersHierarchy,
    required Name name,
    required Member? interfaceTarget,
    required ArgumentsImpl arguments,
    required Uri fileUri,
    required int fileOffset,
  }) {
    if (arguments.types.isEmpty) return;
    Class klass;
    List<DartType> receiverTypeArguments;
    Map<TypeParameter, DartType> substitutionMap = <TypeParameter, DartType>{};
    if (receiverType is InterfaceType) {
      klass = receiverType.classNode;
      receiverTypeArguments = receiverType.typeArguments;
      for (int i = 0; i < receiverTypeArguments.length; ++i) {
        substitutionMap[klass.typeParameters[i]] = receiverTypeArguments[i];
      }
    } else {
      return;
    }
    // TODO(cstefantsova): Find a better way than relying on [interfaceTarget].
    Member? method =
        membersHierarchy.getDispatchTarget(klass, name) ?? interfaceTarget;
    if (method == null || method is! Procedure) {
      return;
    }
    if (klass != method.enclosingClass) {
      Supertype parent = classHierarchy.getClassAsInstanceOf(
        klass,
        method.enclosingClass!,
      )!;
      klass = method.enclosingClass!;
      receiverTypeArguments = parent.typeArguments;
      Map<TypeParameter, DartType> instanceSubstitutionMap = substitutionMap;
      substitutionMap = <TypeParameter, DartType>{};
      for (int i = 0; i < receiverTypeArguments.length; ++i) {
        substitutionMap[klass.typeParameters[i]] = substitute(
          receiverTypeArguments[i],
          instanceSubstitutionMap,
        );
      }
    }
    List<TypeParameter> methodParameters = method.function.typeParameters;
    if (methodParameters.length != arguments.types.length) {
      assert(
        problemReportingHelper.assertProblemReportedElsewhere(
          "SourceLibraryBuilder.checkBoundsInMethodInvocation: "
          "the numbers of type parameters and type arguments don't match.",
          expectedPhase: CompilationPhaseForProblemReporting.outline,
        ),
      );
      return;
    }
    List<TypeParameter> methodTypeParametersOfInstantiated =
        getFreshTypeParameters(methodParameters).freshTypeParameters;
    for (TypeParameter typeParameter in methodTypeParametersOfInstantiated) {
      typeParameter.bound = substitute(typeParameter.bound, substitutionMap);
      typeParameter.defaultType = substitute(
        typeParameter.defaultType,
        substitutionMap,
      );
    }

    final DartType bottomType = const NeverType.nonNullable();
    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
      methodTypeParametersOfInstantiated,
      arguments.types,
      typeEnvironment,
      bottomType,
      areGenericArgumentsAllowed: libraryFeatures.genericMetadata.isEnabled,
    );
    _reportTypeArgumentIssues(
      issues,
      fileUri,
      fileOffset,
      inferred: !arguments.hasExplicitTypeArguments,
      targetReceiver: receiverType,
      targetName: name.text,
    );
  }

  void checkBoundsInStaticInvocation({
    required ProblemReportingHelper problemReportingHelper,
    required LibraryFeatures libraryFeatures,
    required String targetName,
    required TypeEnvironment typeEnvironment,
    required Uri fileUri,
    required List<TypeParameter> typeParameters,
    required List<DartType> typeArguments,
    required bool explicitTypeArguments,
    required int fileOffset,
  }) {
    if (typeArguments.isEmpty) return;
    if (typeParameters.length != typeArguments.length) {
      assert(
        problemReportingHelper.assertProblemReportedElsewhere(
          "SourceLibraryBuilder.checkBoundsInStaticInvocation: "
          "the numbers of type parameters and type arguments don't match.",
          expectedPhase: CompilationPhaseForProblemReporting.outline,
        ),
      );
      return;
    }

    final DartType bottomType = const NeverType.nonNullable();
    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
      typeParameters,
      typeArguments,
      typeEnvironment,
      bottomType,
      areGenericArgumentsAllowed: libraryFeatures.genericMetadata.isEnabled,
    );
    if (issues.isNotEmpty) {
      _reportTypeArgumentIssues(
        issues,
        fileUri,
        fileOffset,
        inferred: !explicitTypeArguments,
        targetName: targetName,
      );
    }
  }

  void checkBoundsInType({
    required LibraryFeatures libraryFeatures,
    required DartType type,
    required TypeEnvironment typeEnvironment,
    required Uri fileUri,
    required int fileOffset,
    bool? inferred,
    bool allowSuperBounded = true,
  }) {
    List<TypeArgumentIssue> issues = findTypeArgumentIssues(
      type,
      typeEnvironment,
      allowSuperBounded: allowSuperBounded,
      areGenericArgumentsAllowed: libraryFeatures.genericMetadata.isEnabled,
    );
    _reportTypeArgumentIssues(issues, fileUri, fileOffset, inferred: inferred);
  }

  /// Reports an error if [type] contains is a generic function type used as
  /// a type argument through its alias.
  ///
  /// For instance
  ///
  ///   typedef A = B<void Function<T>(T)>;
  ///
  /// here `A` doesn't use a generic function as type argument directly, but
  /// its unaliased value `B<void Function<T>(T)>` does.
  ///
  /// This is used for reporting generic function types used as a type argument,
  /// which was disallowed before the 'generic-metadata' feature was enabled.
  void checkGenericFunctionTypeAsTypeArgumentThroughTypedef({
    required LibraryFeatures libraryFeatures,
    required TypedefType type,
    required Uri fileUri,
    required int fileOffset,
  }) {
    assert(!libraryFeatures.genericMetadata.isEnabled);
    if (!hasGenericFunctionTypeAsTypeArgument(type)) {
      DartType unaliased = type.unalias;
      if (hasGenericFunctionTypeAsTypeArgument(unaliased)) {
        addProblem(
          codeGenericFunctionTypeAsTypeArgumentThroughTypedef.withArgumentsOld(
            unaliased,
            type,
          ),
          fileOffset,
          noLength,
          fileUri,
        );
      }
    }
  }

  void checkGetterSetterTypes({
    required LibraryFeatures libraryFeatures,
    required TypeEnvironment typeEnvironment,
    required DartType getterType,
    required String getterName,
    required UriOffsetLength getterUriOffset,
    required DartType setterType,
    required String setterName,
    required UriOffsetLength setterUriOffset,
  }) {
    if (libraryFeatures.getterSetterError.isEnabled ||
        getterType is InvalidType ||
        setterType is InvalidType) {
      // Don't report a problem because the it isn't considered a problem in the
      // current Dart version or because something else is wrong that has
      // already been reported.
    } else {
      bool isValid = typeEnvironment.isSubtypeOf(getterType, setterType);
      if (!isValid) {
        addProblem2(
          codeInvalidGetterSetterType.withArgumentsOld(
            getterType,
            getterName,
            setterType,
            setterName,
          ),
          getterUriOffset,
          context: [
            codeInvalidGetterSetterTypeSetterContext
                .withArgumentsOld(setterName)
                .withLocation2(setterUriOffset),
          ],
        );
      }
    }
  }

  /// Checks that non-nullable optional parameters have a default value.
  void checkInitializersInFormals({
    required List<FormalParameterBuilder>? formals,
    required TypeEnvironment typeEnvironment,
    required bool isAbstract,
    required bool isExternal,
  }) {
    if (formals != null && !(isAbstract || isExternal)) {
      for (int i = 0; i < formals.length; i++) {
        FormalParameterBuilder formal = formals[i];
        bool isOptionalPositional =
            formal.isOptionalPositional && formal.isPositional;
        bool isOptionalNamed = !formal.isRequiredNamed && formal.isNamed;
        bool isOptional = isOptionalPositional || isOptionalNamed;
        if (isOptional &&
            formal.variable!.type.isPotentiallyNonNullable &&
            !formal.hasDeclaredInitializer) {
          addProblem(
            codeOptionalNonNullableWithoutInitializerError.withArgumentsOld(
              formal.name,
              formal.variable!.type,
            ),
            formal.fileOffset,
            formal.name.length,
            formal.fileUri,
          );
          formal.variable?.isErroneouslyInitialized = true;
        }
      }
    }
  }

  Expression? checkStaticArguments({
    required CompilerContext compilerContext,
    required Member target,
    required Arguments arguments,
    required int fileOffset,
    required Uri fileUri,
  }) {
    List<TypeParameter> typeParameters = target.function!.typeParameters;
    if (target is Constructor) {
      assert(!target.enclosingClass.isAbstract);
      typeParameters = target.enclosingClass.typeParameters;
    }
    LocatedMessage? argMessage = checkArgumentsForFunction(
      function: target.function!,
      arguments: arguments,
      fileOffset: fileOffset,
      fileUri: fileUri,
      typeParameters: typeParameters,
    );
    if (argMessage != null) {
      return buildProblemWithContextFromMember(
        compilerContext: compilerContext,
        name: target.name.text,
        member: target,
        message: argMessage,
        fileUri: fileUri,
      );
    }
    return null;
  }

  void checkTypesInField({
    required TypeEnvironment typeEnvironment,
    required bool isInstanceMember,
    required bool isLate,
    required bool isExternal,
    required bool hasInitializer,
    required DartType fieldType,
    required String name,
    required int nameLength,
    required int nameOffset,
    required Uri fileUri,
  }) {
    // Check that the field has an initializer if its type is potentially
    // non-nullable.

    // Only static and top-level fields are checked here.  Instance fields are
    // checked elsewhere.
    if (!isInstanceMember &&
        !isLate &&
        !isExternal &&
        fieldType is! InvalidType &&
        fieldType.isPotentiallyNonNullable &&
        !hasInitializer) {
      addProblem(
        codeFieldNonNullableWithoutInitializerError.withArgumentsOld(
          name,
          fieldType,
        ),
        nameOffset,
        nameLength,
        fileUri,
      );
    }
  }

  void reportTypeArgumentIssue({
    required Message message,
    required Uri fileUri,
    required int fileOffset,
    TypeParameter? typeParameter,
    DartType? superBoundedAttempt,
    DartType? superBoundedAttemptInverted,
  }) {
    List<LocatedMessage>? context;
    // Skip reporting location for function-type type parameters as it's a
    // limitation of Kernel.
    if (typeParameter != null &&
        typeParameter.fileOffset != -1 &&
        typeParameter.location?.file != null) {
      // It looks like when parameters come from augmentation libraries, they
      // don't have a reportable location.
      (context ??= <LocatedMessage>[]).add(
        codeIncorrectTypeArgumentVariable.withLocation(
          typeParameter.location!.file,
          typeParameter.fileOffset,
          noLength,
        ),
      );
    }
    if (superBoundedAttemptInverted != null && superBoundedAttempt != null) {
      // Coverage-ignore-block(suite): Not run.
      (context ??= <LocatedMessage>[]).add(
        codeSuperBoundedHint
            .withArgumentsOld(superBoundedAttempt, superBoundedAttemptInverted)
            .withLocation(fileUri, fileOffset, noLength),
      );
    }
    addProblem(message, fileOffset, noLength, fileUri, context: context);
  }

  Expression wrapInLocatedProblem({
    required CompilerContext compilerContext,
    required Expression expression,
    required LocatedMessage message,
    List<LocatedMessage>? context,
    bool errorHasBeenReported = false,
    bool includeExpression = true,
  }) {
    // TODO(askesc): Produce explicit error expression wrapping the original.
    // See [issue 29717](https://github.com/dart-lang/sdk/issues/29717)
    int offset = expression.fileOffset;
    if (offset == -1) {
      offset = message.charOffset;
    }
    return buildProblem(
      compilerContext: compilerContext,
      message: message.messageObject,
      fileUri: message.uri!,
      fileOffset: message.charOffset,
      length: message.length,
      context: context,
      expression: includeExpression ? expression : null,
      errorHasBeenReported: errorHasBeenReported,
    );
  }

  Expression wrapInProblem({
    required CompilerContext compilerContext,
    required Expression expression,
    required Message message,
    required Uri fileUri,
    required int fileOffset,
    required int length,
    List<LocatedMessage>? context,
    bool? errorHasBeenReported,
    bool includeExpression = true,
  }) {
    CfeSeverity severity = message.code.severity;
    if (severity == CfeSeverity.error) {
      return wrapInLocatedProblem(
        compilerContext: compilerContext,
        expression: expression,
        message: message.withLocation(fileUri, fileOffset, length),
        context: context,
        errorHasBeenReported:
            errorHasBeenReported ?? expression is InvalidExpression,
        includeExpression: includeExpression,
      );
    } else {
      // Coverage-ignore-block(suite): Not run.
      if (expression is! InvalidExpression) {
        addProblem(message, fileOffset, length, fileUri, context: context);
      }
      return expression;
    }
  }

  void _reportTypeArgumentIssueForStructuralParameter(
    Message message,
    Uri fileUri,
    int fileOffset, {
    TypeParameter? typeParameter,
    DartType? superBoundedAttempt,
    DartType? superBoundedAttemptInverted,
  }) {
    List<LocatedMessage>? context;
    // Skip reporting location for function-type type parameters as it's a
    // limitation of Kernel.
    if (typeParameter != null && typeParameter.location != null) {
      // It looks like when parameters come from augmentation libraries, they
      // don't have a reportable location.
      (context ??= <LocatedMessage>[]).add(
        codeIncorrectTypeArgumentVariable.withLocation(
          typeParameter.location!.file,
          typeParameter.fileOffset,
          noLength,
        ),
      );
    }
    if (superBoundedAttemptInverted != null && superBoundedAttempt != null) {
      (context ??= // Coverage-ignore(suite): Not run.
              <LocatedMessage>[])
          .add(
            codeSuperBoundedHint
                .withArgumentsOld(
                  superBoundedAttempt,
                  superBoundedAttemptInverted,
                )
                .withLocation(fileUri, fileOffset, noLength),
          );
    }
    addProblem(message, fileOffset, noLength, fileUri, context: context);
  }

  void _reportTypeArgumentIssues(
    List<TypeArgumentIssue> issues,
    Uri fileUri,
    int offset, {
    bool? inferred,
    DartType? targetReceiver,
    String? targetName,
  }) {
    for (int i = 0; i < issues.length; i++) {
      TypeArgumentIssue issue = issues[i];
      DartType argument = issue.argument;
      TypeParameter? typeParameter = issue.typeParameter;

      Message message;
      bool issueInferred = inferred ?? false;
      if (issue.isGenericTypeAsArgumentIssue) {
        if (issueInferred) {
          message = codeGenericFunctionTypeInferredAsActualTypeArgument
              .withArgumentsOld(argument);
        } else {
          message = codeGenericFunctionTypeUsedAsActualTypeArgument;
        }
        typeParameter = null;
      } else {
        if (issue.enclosingType == null && targetReceiver != null) {
          if (targetName != null) {
            if (issueInferred) {
              message = codeIncorrectTypeArgumentQualifiedInferred
                  .withArgumentsOld(
                    argument,
                    typeParameter.bound,
                    typeParameter.name!,
                    targetReceiver,
                    targetName,
                  );
            } else {
              message = codeIncorrectTypeArgumentQualified.withArgumentsOld(
                argument,
                typeParameter.bound,
                typeParameter.name!,
                targetReceiver,
                targetName,
              );
            }
          } else {
            if (issueInferred) {
              message = codeIncorrectTypeArgumentInstantiationInferred
                  .withArgumentsOld(
                    argument,
                    typeParameter.bound,
                    typeParameter.name!,
                    targetReceiver,
                  );
            } else {
              message = codeIncorrectTypeArgumentInstantiation.withArgumentsOld(
                argument,
                typeParameter.bound,
                typeParameter.name!,
                targetReceiver,
              );
            }
          }
        } else {
          String enclosingName = issue.enclosingType == null
              ? targetName!
              : getGenericTypeName(issue.enclosingType!);
          if (issueInferred) {
            message = codeIncorrectTypeArgumentInferred.withArgumentsOld(
              argument,
              typeParameter.bound,
              typeParameter.name!,
              enclosingName,
            );
          } else {
            message = codeIncorrectTypeArgument.withArgumentsOld(
              argument,
              typeParameter.bound,
              typeParameter.name!,
              enclosingName,
            );
          }
        }
      }

      // Don't show the hint about an attempted super-bounded type if the issue
      // with the argument is that it's generic.
      _reportTypeArgumentIssueForStructuralParameter(
        message,
        fileUri,
        offset,
        typeParameter: typeParameter,
        superBoundedAttempt: issue.isGenericTypeAsArgumentIssue
            ? null
            : issue.enclosingType,
        superBoundedAttemptInverted: issue.isGenericTypeAsArgumentIssue
            ? null
            : issue.invertedType,
      );
    }
  }
}
