// Copyright (c) 2022, 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.md file.

import 'package:kernel/ast.dart';
import 'package:kernel/src/legacy_erasure.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart' show SubtypeCheckMode;

import '../builder/member_builder.dart';
import '../problems.dart' show unexpected;
import 'inference_visitor_base.dart';
import 'type_schema_environment.dart';

enum ObjectAccessTargetKind {
  /// A valid access to a statically known instance member on a non-nullable
  /// receiver.
  instanceMember,

  /// A potentially nullable access to a statically known instance member. This
  /// is an erroneous case and a compile-time error is reported.
  nullableInstanceMember,

  /// A valid access to a statically known instance Object member on a
  /// potentially nullable receiver.
  objectMember,

  /// A valid access to a statically known super member.
  superMember,

  /// A (non-nullable) access to the `.call` method of a function. This is used
  /// for access on `Function` and on function types.
  callFunction,

  /// A potentially nullable access to the `.call` method of a function. This is
  /// an erroneous case and a compile-time error is reported.
  nullableCallFunction,

  /// A valid access to an extension member.
  extensionMember,

  /// A potentially nullable access to an extension member on an extension of
  /// a non-nullable type. This is an erroneous case and a compile-time error is
  /// reported.
  nullableExtensionMember,

  /// An access on a receiver of type `dynamic`.
  dynamic,

  /// An access on a receiver of type `Never`.
  never,

  /// An access on a receiver of an invalid type. This case is the result of
  /// a previously report error and no error is report this case.
  invalid,

  /// An access to a statically unknown instance member. This is an erroneous
  /// case and a compile-time error is reported.
  missing,

  /// An access to multiple extension members, none of which are most specific.
  /// This is an erroneous case and a compile-time error is reported.
  ambiguous,
}

/// Result for performing an access on an object, like `o.foo`, `o.foo()` and
/// `o.foo = ...`.
abstract class ObjectAccessTarget {
  final ObjectAccessTargetKind kind;

  const ObjectAccessTarget.internal(this.kind);

  /// Creates an access to the instance [member].
  factory ObjectAccessTarget.interfaceMember(
      DartType receiverType, Member member,
      {required bool isPotentiallyNullable}) {
    // ignore: unnecessary_null_comparison
    assert(member != null);
    // ignore: unnecessary_null_comparison
    assert(isPotentiallyNullable != null);
    return isPotentiallyNullable
        ? new InstanceAccessTarget.nullable(receiverType, member)
        : new InstanceAccessTarget.nonNullable(receiverType, member);
  }

  /// Creates an access to the super [member].
  factory ObjectAccessTarget.superMember(DartType receiverType, Member member) =
      InstanceAccessTarget.superMember;

  /// Creates an access to the Object [member].
  factory ObjectAccessTarget.objectMember(
      DartType receiverType, Member member) = InstanceAccessTarget.object;

  /// Creates an access to the extension [member].
  factory ObjectAccessTarget.extensionMember(
      DartType receiverType,
      Member member,
      Member? tearoffTarget,
      ProcedureKind kind,
      List<DartType> inferredTypeArguments,
      {bool isPotentiallyNullable}) = ExtensionAccessTarget;

  /// Creates an access to a 'call' method on a function, i.e. a function
  /// invocation.
  factory ObjectAccessTarget.callFunction(DartType receiverType) =
      FunctionAccessTarget.nonNullable;

  /// Creates an access to a 'call' method on a potentially nullable function,
  /// i.e. a function invocation.
  factory ObjectAccessTarget.nullableCallFunction(DartType receiverType) =
      FunctionAccessTarget.nullable;

  /// Creates an access on a dynamic receiver type with no known target.
  const factory ObjectAccessTarget.dynamic() = DynamicAccessTarget.dynamic;

  /// Creates an access on a receiver of type Never with no known target.
  const factory ObjectAccessTarget.never() = DynamicAccessTarget.never;

  /// Creates an access with no target due to an invalid receiver type.
  ///
  /// This is not in itself an error but a consequence of another error.
  const factory ObjectAccessTarget.invalid() = DynamicAccessTarget.invalid;

  /// Creates an access with no target.
  ///
  /// This is an error case.
  const factory ObjectAccessTarget.missing() = DynamicAccessTarget.missing;

  DartType? get receiverType;

  Member? get member;

  /// Returns `true` if this is an access to an instance member.
  bool get isInstanceMember => kind == ObjectAccessTargetKind.instanceMember;

  /// Returns `true` if this is an access to a super member.
  bool get isSuperMember => kind == ObjectAccessTargetKind.superMember;

  /// Returns `true` if this is an access to an Object member.
  bool get isObjectMember => kind == ObjectAccessTargetKind.objectMember;

  /// Returns `true` if this is an access to an extension member.
  bool get isExtensionMember => kind == ObjectAccessTargetKind.extensionMember;

  /// Returns `true` if this is an access to the 'call' method on a function.
  bool get isCallFunction => kind == ObjectAccessTargetKind.callFunction;

  /// Returns `true` if this is an access to the 'call' method on a potentially
  /// nullable function.
  bool get isNullableCallFunction =>
      kind == ObjectAccessTargetKind.nullableCallFunction;

  /// Returns `true` if this is an access on a `dynamic` receiver type.
  bool get isDynamic => kind == ObjectAccessTargetKind.dynamic;

  /// Returns `true` if this is an access on a `Never` receiver type.
  bool get isNever => kind == ObjectAccessTargetKind.never;

  /// Returns `true` if this is an access on an invalid receiver type.
  bool get isInvalid => kind == ObjectAccessTargetKind.invalid;

  /// Returns `true` if this is an access with no target.
  bool get isMissing => kind == ObjectAccessTargetKind.missing;

  /// Returns `true` if this is an access with no unambiguous target. This
  /// occurs when an implicit extension access is ambiguous.
  bool get isAmbiguous => kind == ObjectAccessTargetKind.ambiguous;

  /// Returns `true` if this is an access to an instance member on a potentially
  /// nullable receiver.
  bool get isNullableInstanceMember =>
      kind == ObjectAccessTargetKind.nullableInstanceMember;

  /// Returns `true` if this is an access to an instance member on a potentially
  /// nullable receiver.
  bool get isNullableExtensionMember =>
      kind == ObjectAccessTargetKind.nullableExtensionMember;

  /// Returns `true` if this is an access to an instance member on a potentially
  /// nullable receiver.
  bool get isNullable =>
      isNullableInstanceMember ||
      isNullableCallFunction ||
      isNullableExtensionMember;

  /// Returns the candidates for an ambiguous extension access.
  List<ExtensionAccessCandidate> get candidates =>
      throw new UnsupportedError('ObjectAccessTarget.candidates');

  /// Returns the original procedure kind, if this is an extension method
  /// target.
  ///
  /// This is need because getters, setters, and methods are converted into
  /// top level methods, but access and invocation should still be treated as
  /// if they are the original procedure kind.
  ProcedureKind get extensionMethodKind =>
      throw new UnsupportedError('ObjectAccessTarget.extensionMethodKind');

  /// Returns inferred type arguments for the type parameters of an extension
  /// method that comes from the extension declaration.
  List<DartType> get inferredExtensionTypeArguments =>
      throw new UnsupportedError(
          'ObjectAccessTarget.inferredExtensionTypeArguments');

  /// Returns the member to use for a tearoff.
  ///
  /// This is currently used for extension methods.
  // TODO(johnniwinther): Normalize use by having `readTarget` and
  //  `invokeTarget`?
  Member? get tearoffTarget =>
      throw new UnsupportedError('ObjectAccessTarget.tearoffTarget');

  FunctionType _getFunctionType(
      InferenceVisitorBase base, DartType calleeType) {
    calleeType = base.resolveTypeParameter(calleeType);
    if (calleeType is FunctionType) {
      if (!base.isNonNullableByDefault) {
        calleeType = legacyErasure(calleeType);
      }
      return calleeType as FunctionType;
    }
    return base.unknownFunction;
  }

  /// Returns the type of this target when accessed as an invocation on
  /// [receiverType].
  ///
  /// If the target is known not to be invokable
  /// [InferenceVisitorBase.unknownFunction] is returned.
  ///
  /// For instance
  ///
  ///    abstract class Class<T> {
  ///      T method();
  ///      T Function() get getter1;
  ///      T get getter2;
  ///    }
  ///
  ///    Class<int> c = ...
  ///    c.method; // The getter type is `int Function()`.
  ///    c.getter1; // The getter type is `int Function()`.
  ///    c.getter2; // The getter type is [unknownFunction].
  ///
  FunctionType getFunctionType(InferenceVisitorBase base);

  /// Returns the type of this target when accessed as a getter on
  /// [receiverType].
  ///
  /// For instance
  ///
  ///    abstract class Class<T> {
  ///      T method();
  ///      T get getter;
  ///    }
  ///
  ///    Class<int> c = ...
  ///    c.method; // The getter type is `int Function()`.
  ///    c.getter; // The getter type is `int`.
  ///
  DartType getGetterType(InferenceVisitorBase base);

  /// Returns the type of this target when accessed as a setter on
  /// [receiverType].
  ///
  /// For instance
  ///
  ///    class Class<T> {
  ///      void set setter(T value) {}
  ///    }
  ///
  ///    Class<int> c = ...
  ///    c.setter = 42; // The setter type is `int`.
  ///
  DartType getSetterType(InferenceVisitorBase base);

  /// Returns `true` if this target is binary operator, whose return type is
  /// specialized to take the operand type into account.
  ///
  /// This is for instance the case for `int.+` which returns `int` when the
  /// operand is of type `int` and `num` otherwise.
  bool isSpecialCasedBinaryOperator(InferenceVisitorBase base) => false;

  /// Returns `true` if this target is ternary operator, whose return type is
  /// specialized to take the operand type into account.
  ///
  /// This is for instance the case for `int.clamp` which returns `int` when the
  /// operands are of type `int` and `num` otherwise.
  bool isSpecialCasedTernaryOperator(InferenceVisitorBase base) => false;

  /// Returns the type of the 'key' parameter in an [] or []= implementation.
  ///
  /// For instance
  ///
  ///    class Class<K, V> {
  ///      V operator [](K key) => throw '';
  ///      void operator []=(K key, V value) {}
  ///    }
  ///
  ///    extension Extension<K, V> on Class<K, V> {
  ///      V operator [](K key) => throw '';
  ///      void operator []=(K key, V value) {}
  ///    }
  ///
  ///    new Class<int, String>()[0];             // The key type is `int`.
  ///    new Class<int, String>()[0] = 'foo';     // The key type is `int`.
  ///    Extension<int, String>(null)[0];         // The key type is `int`.
  ///    Extension<int, String>(null)[0] = 'foo'; // The key type is `int`.
  ///
  DartType getIndexKeyType(InferenceVisitorBase base);

  /// Returns the type of the 'value' parameter in an []= implementation.
  ///
  /// For instance
  ///
  ///    class Class<K, V> {
  ///      void operator []=(K key, V value) {}
  ///    }
  ///
  ///    extension Extension<K, V> on Class<K, V> {
  ///      void operator []=(K key, V value) {}
  ///    }
  ///
  ///    new Class<int, String>()[0] = 'foo';     // The value type is `String`.
  ///    Extension<int, String>(null)[0] = 'foo'; // The value type is `String`.
  ///
  DartType getIndexSetValueType(InferenceVisitorBase base);

  /// Returns the return type of the invocation of this target on
  /// [receiverType].
  ///
  /// If the target is known not to be invokable `dynamic` is returned.
  ///
  /// For instance
  ///
  ///    abstract class Class<T> {
  ///      T method();
  ///      T Function() get getter1;
  ///      T get getter2;
  ///    }
  ///
  ///    Class<int> c = ...
  ///    c.method(); // The return type is `int`.
  ///    c.getter1(); // The return type is `int`.
  ///    c.getter2(); // The return type is `dynamic`.
  ///
  // TODO(johnniwinther): Cleanup [getFunctionType], [getReturnType],
  // [getIndexKeyType] and [getIndexSetValueType]. We shouldn't need that many.
  DartType getReturnType(InferenceVisitorBase base);

  /// Returns the operand type of this target accessed as a binary operation
  /// on [receiverType].
  ///
  /// For instance
  ///
  ///    abstract class Class<T> {
  ///      T operator +(T t);
  ///      T operator - (List<T> t);
  ///    }
  ///
  ///    Class<int> c = ...
  ///    c + 0; // The operand type is `int`.
  ///    c - [0]; // The operand type is `List<int>`.
  ///
  DartType getBinaryOperandType(InferenceVisitorBase base);

  @override
  String toString() => 'ObjectAccessTarget($kind,$member)';
}

class InstanceAccessTarget extends ObjectAccessTarget {
  @override
  final DartType receiverType;
  @override
  final Member member;

  /// Creates an access to the instance [member].
  InstanceAccessTarget.nonNullable(this.receiverType, this.member)
      : super.internal(ObjectAccessTargetKind.instanceMember);

  /// Creates an access to the instance [member].
  InstanceAccessTarget.nullable(this.receiverType, this.member)
      : super.internal(ObjectAccessTargetKind.nullableInstanceMember);

  /// Creates an access to the super [member].
  InstanceAccessTarget.superMember(this.receiverType, this.member)
      : super.internal(ObjectAccessTargetKind.superMember);

  /// Creates an access to the Object [member].
  InstanceAccessTarget.object(this.receiverType, this.member)
      : super.internal(ObjectAccessTargetKind.objectMember);

  @override
  FunctionType getFunctionType(InferenceVisitorBase base) {
    return _getFunctionType(
        base,
        base.getGetterTypeForMemberTarget(member, receiverType,
            isSuper: isSuperMember));
  }

  @override
  DartType getGetterType(InferenceVisitorBase base) {
    return base.getGetterTypeForMemberTarget(member, receiverType,
        isSuper: isSuperMember);
  }

  @override
  DartType getSetterType(InferenceVisitorBase base) {
    Member interfaceMember = member;
    Class memberClass = interfaceMember.enclosingClass!;
    assert(
        interfaceMember is Field && interfaceMember.hasSetter ||
            interfaceMember is Procedure && interfaceMember.isSetter,
        "Unexpected setter target $interfaceMember");
    DartType setterType = isSuperMember
        ? interfaceMember.superSetterType
        : interfaceMember.setterType;
    if (memberClass.typeParameters.isNotEmpty) {
      DartType resolvedReceiverType = base.resolveTypeParameter(receiverType);
      if (resolvedReceiverType is InterfaceType) {
        setterType = Substitution.fromPairs(
                memberClass.typeParameters,
                base.classHierarchy.getTypeArgumentsAsInstanceOf(
                    resolvedReceiverType, memberClass)!)
            .substituteType(setterType);
      }
    }
    if (!base.isNonNullableByDefault) {
      setterType = legacyErasure(setterType);
    }
    return setterType;
  }

  @override
  bool isSpecialCasedBinaryOperator(InferenceVisitorBase base) {
    return member is Procedure &&
        base.typeSchemaEnvironment.isSpecialCasesBinaryForReceiverType(
            member as Procedure, receiverType,
            isNonNullableByDefault: base.isNonNullableByDefault);
  }

  @override
  bool isSpecialCasedTernaryOperator(InferenceVisitorBase base) {
    return member is Procedure &&
        base.typeSchemaEnvironment.isSpecialCasedTernaryOperator(
            member as Procedure,
            isNonNullableByDefault: base.isNonNullableByDefault);
  }

  @override
  DartType getIndexKeyType(InferenceVisitorBase base) {
    FunctionType functionType = _getFunctionType(
        base,
        base.getGetterTypeForMemberTarget(member, receiverType,
            isSuper: isSuperMember));
    if (functionType.positionalParameters.length >= 1) {
      return functionType.positionalParameters[0];
    }
    return const DynamicType();
  }

  @override
  DartType getIndexSetValueType(InferenceVisitorBase base) {
    FunctionType functionType = _getFunctionType(
        base,
        base.getGetterTypeForMemberTarget(member, receiverType,
            isSuper: isSuperMember));
    if (functionType.positionalParameters.length >= 2) {
      return functionType.positionalParameters[1];
    }
    return const DynamicType();
  }

  @override
  DartType getReturnType(InferenceVisitorBase base) {
    FunctionType functionType = _getFunctionType(
        base,
        base.getGetterTypeForMemberTarget(member, receiverType,
            isSuper: isSuperMember));
    return functionType.returnType;
  }

  @override
  DartType getBinaryOperandType(InferenceVisitorBase base) {
    FunctionType functionType = _getFunctionType(
        base,
        base.getGetterTypeForMemberTarget(member, receiverType,
            isSuper: isSuperMember));
    if (functionType.positionalParameters.isNotEmpty) {
      return functionType.positionalParameters.first;
    }
    return const DynamicType();
  }
}

class FunctionAccessTarget extends ObjectAccessTarget {
  @override
  final DartType receiverType;

  /// Creates an access to a 'call' method on a function, i.e. a function
  /// invocation.
  FunctionAccessTarget.nonNullable(this.receiverType)
      : super.internal(ObjectAccessTargetKind.callFunction);

  /// Creates an access to a 'call' method on a potentially nullable function,
  /// i.e. a function invocation.
  FunctionAccessTarget.nullable(this.receiverType)
      : super.internal(ObjectAccessTargetKind.nullableCallFunction);

  @override
  Member? get member => null;

  @override
  FunctionType getFunctionType(InferenceVisitorBase base) {
    return _getFunctionType(base, receiverType);
  }

  @override
  DartType getGetterType(InferenceVisitorBase base) {
    return receiverType;
  }

  @override
  DartType getSetterType(InferenceVisitorBase base) {
    throw unexpected(runtimeType.toString(), 'getSetterType', -1, null);
  }

  @override
  DartType getIndexKeyType(InferenceVisitorBase base) {
    return const DynamicType();
  }

  @override
  DartType getIndexSetValueType(InferenceVisitorBase base) {
    return const DynamicType();
  }

  @override
  DartType getReturnType(InferenceVisitorBase base) {
    return getFunctionType(base).returnType;
  }

  @override
  DartType getBinaryOperandType(InferenceVisitorBase base) {
    return const DynamicType();
  }
}

class DynamicAccessTarget extends ObjectAccessTarget {
  /// Creates an access on a dynamic receiver type with no known target.
  const DynamicAccessTarget.dynamic()
      : super.internal(ObjectAccessTargetKind.dynamic);

  /// Creates an access on a receiver of type Never with no known target.
  const DynamicAccessTarget.never()
      : super.internal(ObjectAccessTargetKind.never);

  /// Creates an access with no target due to an invalid receiver type.
  ///
  /// This is not in itself an error but a consequence of another error.
  const DynamicAccessTarget.invalid()
      : super.internal(ObjectAccessTargetKind.invalid);

  /// Creates an access with no target.
  ///
  /// This is an error case.
  const DynamicAccessTarget.missing()
      : super.internal(ObjectAccessTargetKind.missing);

  @override
  DartType? get receiverType => null;

  @override
  Member? get member => null;

  @override
  FunctionType getFunctionType(InferenceVisitorBase base) {
    return base.unknownFunction;
  }

  @override
  DartType getGetterType(InferenceVisitorBase base) {
    return isInvalid
        ? const InvalidType()
        : (isNever ? const NeverType.nonNullable() : const DynamicType());
  }

  @override
  DartType getSetterType(InferenceVisitorBase base) {
    return isInvalid ? const InvalidType() : const DynamicType();
  }

  @override
  DartType getIndexKeyType(InferenceVisitorBase base) {
    return isInvalid ? const InvalidType() : const DynamicType();
  }

  @override
  DartType getIndexSetValueType(InferenceVisitorBase base) {
    return isInvalid ? const InvalidType() : const DynamicType();
  }

  @override
  DartType getReturnType(InferenceVisitorBase base) {
    return isInvalid
        ? const InvalidType()
        : (isNever ? const NeverType.nonNullable() : const DynamicType());
  }

  @override
  DartType getBinaryOperandType(InferenceVisitorBase base) {
    return isInvalid ? const InvalidType() : const DynamicType();
  }
}

class ExtensionAccessTarget extends ObjectAccessTarget {
  @override
  final DartType receiverType;
  @override
  final Member member;
  @override
  final Member? tearoffTarget;
  @override
  final ProcedureKind extensionMethodKind;
  @override
  final List<DartType> inferredExtensionTypeArguments;

  ExtensionAccessTarget(this.receiverType, this.member, this.tearoffTarget,
      this.extensionMethodKind, this.inferredExtensionTypeArguments,
      {bool isPotentiallyNullable: false})
      : super.internal(isPotentiallyNullable
            ? ObjectAccessTargetKind.nullableExtensionMember
            : ObjectAccessTargetKind.extensionMember);

  @override
  FunctionType getFunctionType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Method:
      case ProcedureKind.Operator:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        if (!base.isNonNullableByDefault) {
          functionType = legacyErasure(functionType) as FunctionType;
        }
        return functionType;
      case ProcedureKind.Getter:
        // TODO(johnniwinther): Handle implicit .call on extension getter.
        return _getFunctionType(base, member.function!.returnType);
      case ProcedureKind.Setter:
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getFunctionType', -1, null);
    }
  }

  @override
  DartType getGetterType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Method:
      case ProcedureKind.Operator:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        List<TypeParameter> extensionTypeParameters = functionType
            .typeParameters
            .take(inferredExtensionTypeArguments.length)
            .toList();
        Substitution substitution = Substitution.fromPairs(
            extensionTypeParameters, inferredExtensionTypeArguments);
        DartType resultType = substitution.substituteType(new FunctionType(
            functionType.positionalParameters.skip(1).toList(),
            functionType.returnType,
            base.libraryBuilder.nonNullable,
            namedParameters: functionType.namedParameters,
            typeParameters: functionType.typeParameters
                .skip(inferredExtensionTypeArguments.length)
                .toList(),
            requiredParameterCount: functionType.requiredParameterCount - 1));
        if (!base.isNonNullableByDefault) {
          resultType = legacyErasure(resultType);
        }
        return resultType;
      case ProcedureKind.Getter:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        List<TypeParameter> extensionTypeParameters = functionType
            .typeParameters
            .take(inferredExtensionTypeArguments.length)
            .toList();
        Substitution substitution = Substitution.fromPairs(
            extensionTypeParameters, inferredExtensionTypeArguments);
        DartType resultType =
            substitution.substituteType(functionType.returnType);
        if (!base.isNonNullableByDefault) {
          resultType = legacyErasure(resultType);
        }
        return resultType;
      case ProcedureKind.Setter:
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getGetterType', -1, null);
    }
  }

  @override
  DartType getSetterType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Setter:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        List<TypeParameter> extensionTypeParameters = functionType
            .typeParameters
            .take(inferredExtensionTypeArguments.length)
            .toList();
        Substitution substitution = Substitution.fromPairs(
            extensionTypeParameters, inferredExtensionTypeArguments);
        DartType setterType =
            substitution.substituteType(functionType.positionalParameters[1]);
        if (!base.isNonNullableByDefault) {
          setterType = legacyErasure(setterType);
        }
        return setterType;
      case ProcedureKind.Method:
      case ProcedureKind.Getter:
      case ProcedureKind.Operator:
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getSetterType', -1, null);
    }
  }

  @override
  DartType getIndexKeyType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Operator:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        if (functionType.positionalParameters.length >= 2) {
          DartType keyType = functionType.positionalParameters[1];
          if (functionType.typeParameters.isNotEmpty) {
            Substitution substitution = Substitution.fromPairs(
                functionType.typeParameters, inferredExtensionTypeArguments);
            keyType = substitution.substituteType(keyType);
          }
          if (!base.isNonNullableByDefault) {
            keyType = legacyErasure(keyType);
          }
          return keyType;
        }
        return const InvalidType();
      case ProcedureKind.Method:
      case ProcedureKind.Getter:
      case ProcedureKind.Setter:
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getIndexKeyType', -1, null);
    }
  }

  @override
  DartType getIndexSetValueType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Operator:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        if (functionType.positionalParameters.length >= 3) {
          DartType indexType = functionType.positionalParameters[2];
          if (functionType.typeParameters.isNotEmpty) {
            Substitution substitution = Substitution.fromPairs(
                functionType.typeParameters, inferredExtensionTypeArguments);
            indexType = substitution.substituteType(indexType);
          }
          if (!base.isNonNullableByDefault) {
            indexType = legacyErasure(indexType);
          }
          return indexType;
        }
        return const InvalidType();
      case ProcedureKind.Method:
      case ProcedureKind.Getter:
      case ProcedureKind.Setter:
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getIndexSetValueType', -1, null);
    }
  }

  @override
  DartType getReturnType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Operator:
      case ProcedureKind.Method:
      case ProcedureKind.Getter:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        DartType returnType = functionType.returnType;
        if (functionType.typeParameters.isNotEmpty) {
          Substitution substitution = Substitution.fromPairs(
              functionType.typeParameters, inferredExtensionTypeArguments);
          returnType = substitution.substituteType(returnType);
        }
        if (!base.isNonNullableByDefault) {
          returnType = legacyErasure(returnType);
        }
        return returnType;
      case ProcedureKind.Setter:
        return const VoidType();
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getReturnType', -1, null);
    }
  }

  @override
  DartType getBinaryOperandType(InferenceVisitorBase base) {
    switch (extensionMethodKind) {
      case ProcedureKind.Operator:
        FunctionType functionType = member.function!
            .computeFunctionType(base.libraryBuilder.nonNullable);
        if (functionType.positionalParameters.length > 1) {
          DartType keyType = functionType.positionalParameters[1];
          if (functionType.typeParameters.isNotEmpty) {
            Substitution substitution = Substitution.fromPairs(
                functionType.typeParameters, inferredExtensionTypeArguments);
            keyType = substitution.substituteType(keyType);
          }
          if (!base.isNonNullableByDefault) {
            keyType = legacyErasure(keyType);
          }
          return keyType;
        }
        return const InvalidType();
      case ProcedureKind.Method:
      case ProcedureKind.Getter:
      case ProcedureKind.Setter:
        return const InvalidType();
      case ProcedureKind.Factory:
        throw unexpected('$this', 'getBinaryOperandType', -1, null);
    }
  }

  @override
  String toString() =>
      'ExtensionAccessTarget($kind,$member,$extensionMethodKind,'
      '$inferredExtensionTypeArguments)';
}

class AmbiguousExtensionAccessTarget extends ObjectAccessTarget {
  @override
  final DartType receiverType;

  @override
  final List<ExtensionAccessCandidate> candidates;

  AmbiguousExtensionAccessTarget(this.receiverType, this.candidates)
      : super.internal(ObjectAccessTargetKind.ambiguous);

  @override
  Member? get member => null;

  @override
  FunctionType getFunctionType(InferenceVisitorBase base) {
    return base.unknownFunction;
  }

  @override
  DartType getGetterType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  DartType getSetterType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  DartType getIndexKeyType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  DartType getIndexSetValueType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  DartType getReturnType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  DartType getBinaryOperandType(InferenceVisitorBase base) {
    return const InvalidType();
  }

  @override
  String toString() => 'AmbiguousExtensionAccessTarget($kind,$candidates)';
}

class ExtensionAccessCandidate {
  final MemberBuilder memberBuilder;
  final bool isPlatform;
  final DartType onType;
  final DartType onTypeInstantiateToBounds;
  final ObjectAccessTarget target;

  ExtensionAccessCandidate(this.memberBuilder, this.onType,
      this.onTypeInstantiateToBounds, this.target,
      {required this.isPlatform})
      // ignore: unnecessary_null_comparison
      : assert(isPlatform != null);

  bool? isMoreSpecificThan(TypeSchemaEnvironment typeSchemaEnvironment,
      ExtensionAccessCandidate other) {
    if (this.isPlatform == other.isPlatform) {
      // Both are platform or not platform.
      bool thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
          this.onType, other.onType, SubtypeCheckMode.withNullabilities);
      bool thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
          other.onType, this.onType, SubtypeCheckMode.withNullabilities);
      if (thisIsSubtype && !thisIsSupertype) {
        // This is subtype of other and not vice-versa.
        return true;
      } else if (thisIsSupertype && !thisIsSubtype) {
        // [other] is subtype of this and not vice-versa.
        return false;
      } else if (thisIsSubtype || thisIsSupertype) {
        thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
            this.onTypeInstantiateToBounds,
            other.onTypeInstantiateToBounds,
            SubtypeCheckMode.withNullabilities);
        thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
            other.onTypeInstantiateToBounds,
            this.onTypeInstantiateToBounds,
            SubtypeCheckMode.withNullabilities);
        if (thisIsSubtype && !thisIsSupertype) {
          // This is subtype of other and not vice-versa.
          return true;
        } else if (thisIsSupertype && !thisIsSubtype) {
          // [other] is subtype of this and not vice-versa.
          return false;
        }
      }
    } else if (other.isPlatform) {
      // This is not platform, [other] is: this  is more specific.
      return true;
    } else {
      // This is platform, [other] is not: other is more specific.
      return false;
    }
    // Neither is more specific than the other.
    return null;
  }
}
