// Copyright (c) 2016, 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.

library fasta.source_class_builder;

import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart'
    show ClassHierarchy, ClassHierarchyBase, ClassHierarchyMembers;
import 'package:kernel/core_types.dart';
import 'package:kernel/reference_from_index.dart' show IndexedClass;
import 'package:kernel/src/bounds_checks.dart';
import 'package:kernel/src/legacy_erasure.dart';
import 'package:kernel/src/types.dart' show Types;
import 'package:kernel/type_algebra.dart'
    show
        FreshTypeParameters,
        Substitution,
        getFreshTypeParameters,
        substitute,
        updateBoundNullabilities;
import 'package:kernel/type_environment.dart';

import '../builder/builder.dart';
import '../builder/class_builder.dart';
import '../builder/constructor_reference_builder.dart';
import '../builder/function_builder.dart';
import '../builder/invalid_type_declaration_builder.dart';
import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/name_iterator.dart';
import '../builder/named_type_builder.dart';
import '../builder/never_type_declaration_builder.dart';
import '../builder/nullability_builder.dart';
import '../builder/type_alias_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_declaration_builder.dart';
import '../builder/type_variable_builder.dart';
import '../builder/void_type_declaration_builder.dart';
import '../dill/dill_member_builder.dart';
import '../fasta_codes.dart';
import '../kernel/combined_member_signature.dart';
import '../kernel/hierarchy/hierarchy_builder.dart';
import '../kernel/hierarchy/hierarchy_node.dart';
import '../kernel/kernel_helper.dart';
import '../kernel/kernel_target.dart' show KernelTarget;
import '../kernel/redirecting_factory_body.dart'
    show RedirectingFactoryBody, redirectingName;
import '../kernel/type_algorithms.dart' show computeTypeVariableBuilderVariance;
import '../kernel/utils.dart' show compareProcedures;
import '../identifiers.dart';
import '../names.dart' show equalsName, noSuchMethodName;
import '../problems.dart' show unexpected, unhandled, unimplemented;
import '../scope.dart';
import '../type_inference/type_schema.dart';
import '../util/helpers.dart';
import 'source_constructor_builder.dart';
import 'source_factory_builder.dart';
import 'source_field_builder.dart';
import 'source_library_builder.dart';
import 'source_member_builder.dart';

Class initializeClass(
    Class? cls,
    List<TypeVariableBuilder>? typeVariables,
    String name,
    SourceLibraryBuilder parent,
    int startCharOffset,
    int charOffset,
    int charEndOffset,
    IndexedClass? referencesFrom,
    {required bool isAugmentation}) {
  cls ??= new Class(
      name: name,
      typeParameters:
          TypeVariableBuilder.typeParametersFromBuilders(typeVariables),
      // If the class is an augmentation class it shouldn't use the reference
      // from index even when available.
      // TODO(johnniwinther): Avoid creating [Class] so early in the builder
      // that we end up creating unneeded nodes.
      reference: isAugmentation ? null : referencesFrom?.cls.reference,
      fileUri: parent.fileUri);
  if (cls.startFileOffset == TreeNode.noOffset) {
    cls.startFileOffset = startCharOffset;
  }
  if (cls.fileOffset == TreeNode.noOffset) {
    cls.fileOffset = charOffset;
  }
  if (cls.fileEndOffset == TreeNode.noOffset) {
    cls.fileEndOffset = charEndOffset;
  }

  return cls;
}

class SourceClassBuilder extends ClassBuilderImpl
    implements Comparable<SourceClassBuilder> {
  final Class actualCls;

  final List<ConstructorReferenceBuilder>? constructorReferences;

  @override
  TypeBuilder? mixedInTypeBuilder;

  bool isMixinDeclaration;

  final IndexedClass? referencesFromIndexed;

  @override
  final bool isMacro;

  @override
  final bool isAugmentation;

  List<SourceClassBuilder>? _patches;

  SourceClassBuilder(
      List<MetadataBuilder>? metadata,
      int modifiers,
      String name,
      List<TypeVariableBuilder>? typeVariables,
      TypeBuilder? supertype,
      List<TypeBuilder>? interfaces,
      List<TypeBuilder>? onTypes,
      Scope scope,
      ConstructorScope constructors,
      SourceLibraryBuilder parent,
      this.constructorReferences,
      int startCharOffset,
      int nameOffset,
      int charEndOffset,
      this.referencesFromIndexed,
      {Class? cls,
      this.mixedInTypeBuilder,
      this.isMixinDeclaration = false,
      this.isMacro = false,
      this.isAugmentation = false})
      : actualCls = initializeClass(cls, typeVariables, name, parent,
            startCharOffset, nameOffset, charEndOffset, referencesFromIndexed,
            isAugmentation: isAugmentation),
        super(metadata, modifiers, name, typeVariables, supertype, interfaces,
            onTypes, scope, constructors, parent, nameOffset) {
    actualCls.hasConstConstructor = declaresConstConstructor;
  }

  List<SourceClassBuilder>? get patchesForTesting => _patches;

  SourceClassBuilder? actualOrigin;

  @override
  SourceClassBuilder get origin => actualOrigin ?? this;

  @override
  Class get cls => origin.actualCls;

  @override
  SourceLibraryBuilder get libraryBuilder =>
      super.libraryBuilder as SourceLibraryBuilder;

  Class build(LibraryBuilder coreLibrary) {
    SourceLibraryBuilder.checkMemberConflicts(libraryBuilder, scope,
        // These checks are performed as part of the class hierarchy
        // computation.
        checkForInstanceVsStaticConflict: false,
        checkForMethodVsSetterConflict: false);

    void buildBuilders(Builder declaration) {
      if (declaration.parent != this) {
        if (declaration.parent?.origin != this) {
          if (fileUri != declaration.parent?.fileUri) {
            unexpected("$fileUri", "${declaration.parent?.fileUri}", charOffset,
                fileUri);
          } else {
            unexpected(
                fullNameForErrors,
                declaration.parent?.fullNameForErrors ?? '',
                charOffset,
                fileUri);
          }
        }
      } else if (declaration is SourceMemberBuilder) {
        SourceMemberBuilder memberBuilder = declaration;
        memberBuilder
            .buildOutlineNodes((Member member, BuiltMemberKind memberKind) {
          member.parent = cls;
          if (!memberBuilder.isPatch &&
              !memberBuilder.isDuplicate &&
              !memberBuilder.isConflictingSetter &&
              !memberBuilder.isConflictingAugmentationMember) {
            if (member is Procedure) {
              cls.addProcedure(member);
            } else if (member is Field) {
              cls.addField(member);
            } else if (member is Constructor) {
              cls.addConstructor(member);
            } else if (member is RedirectingFactory) {
              cls.addRedirectingFactory(member);
            } else {
              unhandled("${member.runtimeType}", "getMember", member.fileOffset,
                  member.fileUri);
            }
          }
        });
      } else {
        unhandled("${declaration.runtimeType}", "buildBuilders",
            declaration.charOffset, declaration.fileUri);
      }
    }

    scope.unfilteredIterator.forEach(buildBuilders);
    constructorScope.unfilteredIterator.forEach(buildBuilders);
    if (supertypeBuilder != null) {
      supertypeBuilder = _checkSupertype(supertypeBuilder!);
    }
    Supertype? supertype = supertypeBuilder?.buildSupertype(libraryBuilder);
    if (supertype != null) {
      Class superclass = supertype.classNode;
      if (superclass.name == 'Function' &&
          superclass.enclosingLibrary == coreLibrary.library) {
        libraryBuilder.addProblem(
            messageExtendFunction, charOffset, noLength, fileUri);
        supertype = null;
        supertypeBuilder = null;
      }
    }
    if (!isMixinDeclaration &&
        actualCls.supertype != null &&
        actualCls.superclass!.isMixinDeclaration) {
      // Declared mixins have interfaces that can be implemented, but they
      // cannot be extended.  However, a mixin declaration with a single
      // superclass constraint is encoded with the constraint as the supertype,
      // and that is allowed to be a mixin's interface.
      libraryBuilder.addProblem(
          templateSupertypeIsIllegal.withArguments(actualCls.superclass!.name),
          charOffset,
          noLength,
          fileUri);
      supertype = null;
    }
    if (supertype == null && supertypeBuilder is! NamedTypeBuilder) {
      supertypeBuilder = null;
    }
    actualCls.supertype = supertype;

    if (mixedInTypeBuilder != null) {
      mixedInTypeBuilder = _checkSupertype(mixedInTypeBuilder!);
    }
    Supertype? mixedInType =
        mixedInTypeBuilder?.buildMixedInType(libraryBuilder);
    if (_isFunction(mixedInType, coreLibrary)) {
      libraryBuilder.addProblem(
          messageMixinFunction, charOffset, noLength, fileUri);
      mixedInType = null;
      mixedInTypeBuilder = null;
      actualCls.isAnonymousMixin = false;
      isMixinDeclaration = false;
    }
    if (mixedInType == null && mixedInTypeBuilder is! NamedTypeBuilder) {
      mixedInTypeBuilder = null;
    }
    actualCls.isMixinDeclaration = isMixinDeclaration;
    actualCls.mixedInType = mixedInType;

    // TODO(ahe): If `cls.supertype` is null, and this isn't Object, report a
    // compile-time error.
    cls.isAbstract = isAbstract;
    cls.isMacro = isMacro;
    if (interfaceBuilders != null) {
      for (int i = 0; i < interfaceBuilders!.length; ++i) {
        interfaceBuilders![i] = _checkSupertype(interfaceBuilders![i]);
        Supertype? supertype =
            interfaceBuilders![i].buildSupertype(libraryBuilder);
        if (supertype != null) {
          if (_isFunction(supertype, coreLibrary)) {
            libraryBuilder.addProblem(
                messageImplementFunction, charOffset, noLength, fileUri);
            continue;
          }
          // TODO(ahe): Report an error if supertype is null.
          actualCls.implementedTypes.add(supertype);
        }
      }
    }

    constructorScope.forEach((String name, Builder constructor) {
      Builder? member = scope.lookupLocalMember(name, setter: false);
      if (member == null) return;
      if (!member.isStatic) return;
      // TODO(ahe): Revisit these messages. It seems like the last two should
      // be `context` parameter to this message.
      addProblem(templateConflictsWithMember.withArguments(name),
          constructor.charOffset, noLength);
      if (constructor.isFactory) {
        addProblem(
            templateConflictsWithFactory.withArguments("${this.name}.${name}"),
            member.charOffset,
            noLength);
      } else {
        addProblem(
            templateConflictsWithConstructor
                .withArguments("${this.name}.${name}"),
            member.charOffset,
            noLength);
      }
    });

    scope.forEachLocalSetter((String name, Builder setter) {
      Builder? constructor = constructorScope.lookupLocalMember(name);
      if (constructor == null || !setter.isStatic) return;
      addProblem(templateConflictsWithConstructor.withArguments(name),
          setter.charOffset, noLength);
      addProblem(templateConflictsWithSetter.withArguments(name),
          constructor.charOffset, noLength);
    });

    cls.procedures.sort(compareProcedures);
    return cls;
  }

  bool _isFunction(Supertype? supertype, LibraryBuilder coreLibrary) {
    if (supertype != null) {
      Class superclass = supertype.classNode;
      if (superclass.name == 'Function' &&
          // We use `superclass.parent` here instead of
          // `superclass.enclosingLibrary` to handle platform compilation. If
          // we are currently compiling the platform, the enclosing library of
          // `Function` has not yet been set, so the accessing
          // `enclosingLibrary` would result in a cast error. We assume that the
          // SDK does not contain this error, which we otherwise not find. If we
          // are _not_ compiling the platform, the `superclass.parent` has been
          // set, if it is `Function` from `dart:core`.
          superclass.parent == coreLibrary.library) {
        return true;
      }
    }
    return false;
  }

  void buildOutlineExpressions(
      ClassHierarchy classHierarchy,
      List<DelayedActionPerformer> delayedActionPerformers,
      List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
    void build(Builder declaration) {
      SourceMemberBuilder member = declaration as SourceMemberBuilder;
      member.buildOutlineExpressions(
          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
    }

    MetadataBuilder.buildAnnotations(isPatch ? origin.cls : cls, metadata,
        libraryBuilder, this, null, fileUri, libraryBuilder.scope);
    if (typeVariables != null) {
      for (int i = 0; i < typeVariables!.length; i++) {
        typeVariables![i].buildOutlineExpressions(libraryBuilder, this, null,
            classHierarchy, delayedActionPerformers, scope.parent!);
      }
    }

    constructorScope
        .filteredIterator(
            parent: this, includeDuplicates: false, includeAugmentations: true)
        .forEach(build);
    scope
        .filteredIterator(
            parent: this, includeDuplicates: false, includeAugmentations: true)
        .forEach(build);
  }

  @override
  void forEach(void f(String name, Builder builder)) {
    new ClassMemberNameIterator(this, includeDuplicates: false).forEach(f);
  }

  @override
  void forEachConstructor(void Function(String, MemberBuilder) f) {
    new ClassConstructorNameIterator(this, includeDuplicates: false).forEach(f);
  }

  void forEachDeclaredField(
      void Function(String name, SourceFieldBuilder fieldBuilder) callback) {
    // Currently, fields can't be patched, but can be injected.  When the fields
    // will be made available for patching, the following code should iterate
    // first over the fields from the patch and then -- over the fields in the
    // original declaration, filtering out the patched fields.  For now, the
    // assert checks that the names of the fields from the original declaration
    // and from the patch don't intersect.
    assert(
        _patches == null ||
            _patches!.every((patchClass) => patchClass.scope.localMembers
                .where((b) => b is SourceFieldBuilder)
                .map((b) => (b as SourceFieldBuilder).name)
                .toSet()
                .intersection(scope.localMembers
                    .where((b) => b is SourceFieldBuilder)
                    .map((b) => (b as SourceFieldBuilder).name)
                    .toSet())
                .isEmpty),
        "Detected an attempt to patch a field.");
    new ClassMemberNameIterator<SourceFieldBuilder>(this,
            includeDuplicates: false)
        .forEach(callback);
  }

  void forEachDeclaredConstructor(
      void Function(
              String name, DeclaredSourceConstructorBuilder constructorBuilder)
          callback) {
    new ClassConstructorNameIterator<DeclaredSourceConstructorBuilder>(this,
            includeDuplicates: false)
        .forEach(callback);
  }

  /// Looks up the constructor by [name] on the class built by this class
  /// builder.
  ///
  /// If [isSuper] is `true`, constructors in the superclass are searched.
  Constructor? lookupConstructor(Name name, {bool isSuper: false}) {
    if (name.text == "new") {
      name = new Name("", name.library);
    }

    Class? instanceClass = cls;
    if (isSuper) {
      instanceClass = instanceClass.superclass;
    }
    if (instanceClass != null) {
      for (Constructor constructor in instanceClass.constructors) {
        if (constructor.name == name) {
          return constructor;
        }
      }
    }

    /// Performs a similar lookup to [lookupConstructor], but using a slower
    /// implementation.
    Constructor? lookupConstructorWithPatches(Name name, bool isSuper) {
      ClassBuilder? builder = this.origin;

      ClassBuilder? getSuperclass(ClassBuilder builder) {
        // This way of computing the superclass is slower than using the kernel
        // objects directly.
        TypeBuilder? supertype = builder.supertypeBuilder;
        if (supertype is NamedTypeBuilder) {
          TypeDeclarationBuilder? builder = supertype.declaration;
          if (builder is ClassBuilder) return builder;
          if (builder is TypeAliasBuilder) {
            TypeDeclarationBuilder? declarationBuilder =
                builder.unaliasDeclaration(supertype.arguments,
                    isUsedAsClass: true,
                    usedAsClassCharOffset: supertype.charOffset,
                    usedAsClassFileUri: supertype.fileUri);
            if (declarationBuilder is ClassBuilder) return declarationBuilder;
          }
        }
        return null;
      }

      if (isSuper) {
        builder = getSuperclass(builder)?.origin;
      }
      if (builder != null) {
        Class cls = builder.cls;
        for (Constructor constructor in cls.constructors) {
          if (constructor.name == name) return constructor;
        }
      }
      return null;
    }

    return lookupConstructorWithPatches(name, isSuper);
  }

  @override
  int get typeVariablesCount => typeVariables?.length ?? 0;

  @override
  List<DartType> buildAliasedTypeArguments(LibraryBuilder library,
      List<TypeBuilder>? arguments, ClassHierarchyBase? hierarchy) {
    if (arguments == null && typeVariables == null) {
      return <DartType>[];
    }

    if (arguments == null && typeVariables != null) {
      // TODO(johnniwinther): Use i2b here when needed.
      List<DartType> result = new List<DartType>.generate(
          typeVariables!.length,
          (int i) => typeVariables![i]
              .defaultType!
              // TODO(johnniwinther): Using [libraryBuilder] here instead of
              // [library] preserves the nullability of the original
              // declaration. Should we legacy erase this?
              .buildAliased(
                  libraryBuilder, TypeUse.defaultTypeAsTypeArgument, hierarchy),
          growable: true);
      if (library is SourceLibraryBuilder) {
        library.inferredTypes.addAll(result);
      }
      return result;
    }

    if (arguments != null && arguments.length != typeVariablesCount) {
      // That should be caught and reported as a compile-time error earlier.
      return unhandled(
          templateTypeArgumentMismatch
              .withArguments(typeVariablesCount)
              .problemMessage,
          "buildTypeArguments",
          -1,
          null);
    }

    assert(arguments!.length == typeVariablesCount);
    List<DartType> result = new List<DartType>.generate(
        arguments!.length,
        (int i) =>
            arguments[i].buildAliased(library, TypeUse.typeArgument, hierarchy),
        growable: true);
    return result;
  }

  /// Returns a map which maps the type variables of [superclass] to their
  /// respective values as defined by the superclass clause of this class (and
  /// its superclasses).
  ///
  /// It's assumed that [superclass] is a superclass of this class.
  ///
  /// For example, given:
  ///
  ///     class Box<T> {}
  ///     class BeatBox extends Box<Beat> {}
  ///     class Beat {}
  ///
  /// We have:
  ///
  ///     [[BeatBox]].getSubstitutionMap([[Box]]) -> {[[Box::T]]: Beat]]}.
  ///
  /// It's an error if [superclass] isn't a superclass.
  Map<TypeParameter, DartType> getSubstitutionMap(Class superclass) {
    Supertype? supertype = cls.supertype;
    Map<TypeParameter, DartType> substitutionMap = <TypeParameter, DartType>{};
    List<DartType> arguments;
    List<TypeParameter> variables;
    Class? classNode;

    while (classNode != superclass) {
      classNode = supertype!.classNode;
      arguments = supertype.typeArguments;
      variables = classNode.typeParameters;
      supertype = classNode.supertype;
      if (variables.isNotEmpty) {
        Map<TypeParameter, DartType> directSubstitutionMap =
            <TypeParameter, DartType>{};
        for (int i = 0; i < variables.length; i++) {
          DartType argument =
              i < arguments.length ? arguments[i] : const DynamicType();
          // ignore: unnecessary_null_comparison
          if (substitutionMap != null) {
            // TODO(ahe): Investigate if requiring the caller to use
            // `substituteDeep` from `package:kernel/type_algebra.dart` instead
            // of `substitute` is faster. If so, we can simply this code.
            argument = substitute(argument, substitutionMap);
          }
          directSubstitutionMap[variables[i]] = argument;
        }
        substitutionMap = directSubstitutionMap;
      }
    }

    return substitutionMap;
  }

  @override
  void applyPatch(Builder patch) {
    if (patch is SourceClassBuilder) {
      patch.actualOrigin = this;
      (_patches ??= []).add(patch);

      void applyAugmentation(String name, SourceMemberBuilder patchMember,
          {required bool setter}) {
        Builder? originMember = scope.lookupLocalMember(name, setter: setter);
        if (patch.isAugmentation) {
          if (originMember != null) {
            if (patchMember.isAugmentation) {
              originMember.applyPatch(patchMember);
            } else {
              patchMember.isConflictingAugmentationMember = true;
              libraryBuilder.addProblem(
                  templateNonAugmentationClassMemberConflict
                      .withArguments(name),
                  patchMember.charOffset,
                  name.length,
                  patchMember.fileUri,
                  context: [
                    messageNonAugmentationClassMemberConflictCause.withLocation(
                        originMember.fileUri!,
                        originMember.charOffset,
                        name.length)
                  ]);
            }
          } else {
            if (patchMember.isAugmentation) {
              libraryBuilder.addProblem(
                  templateUnmatchedAugmentationClassMember.withArguments(name),
                  patchMember.charOffset,
                  name.length,
                  patchMember.fileUri);
            } else {
              scope.addLocalMember(name, patchMember, setter: setter);
            }
          }
        } else {
          if (originMember != null) {
            // Patch class implicitly assume matching members are patch
            // members.
            originMember.applyPatch(patchMember);
          } else {
            // Members injected into patch are not part of the origin scope.
          }
        }
      }

      patch.scope.forEachLocalMember((String name, Builder patchMember) {
        if (patchMember is SourceMemberBuilder) {
          applyAugmentation(name, patchMember, setter: false);
        } else {
          assert(false,
              "Unexpected member ${patchMember} (${patchMember.runtimeType})");
        }
      });

      patch.scope.forEachLocalSetter((String name, Builder patchMember) {
        if (patchMember is SourceMemberBuilder) {
          applyAugmentation(name, patchMember, setter: true);
        } else {
          assert(false,
              "Unexpected member ${patchMember} (${patchMember.runtimeType})");
        }
      });

      patch.constructorScope.local
          .forEach((String name, MemberBuilder patchConstructor) {
        MemberBuilder? originConstructor = constructorScope.local[name];
        if (patch.isAugmentation) {
          if (originConstructor != null) {
            // TODO(johnniwinther): Should we support constructor augmentation?
            // Currently the syntax doesn't allow it.
            originConstructor.applyPatch(patchConstructor);
          } else {
            constructorScope.addLocalMember(name, patchConstructor);
          }
        } else {
          if (originConstructor != null) {
            originConstructor.applyPatch(patchConstructor);
          }
        }
      });

      int originLength = typeVariables?.length ?? 0;
      int patchLength = patch.typeVariables?.length ?? 0;
      if (originLength != patchLength) {
        patch.addProblem(messagePatchClassTypeVariablesMismatch,
            patch.charOffset, noLength, context: [
          messagePatchClassOrigin.withLocation(fileUri, charOffset, noLength)
        ]);
      } else if (typeVariables != null) {
        int count = 0;
        for (TypeVariableBuilder t in patch.typeVariables!) {
          typeVariables![count++].applyPatch(t);
        }
      }
    } else {
      libraryBuilder.addProblem(messagePatchDeclarationMismatch,
          patch.charOffset, noLength, patch.fileUri, context: [
        messagePatchDeclarationOrigin.withLocation(
            fileUri, charOffset, noLength)
      ]);
    }
  }

  void checkSupertypes(
      CoreTypes coreTypes,
      ClassHierarchyBuilder hierarchyBuilder,
      Class objectClass,
      Class enumClass,
      Class underscoreEnumClass,
      Class? macroClass) {
    // This method determines whether the class (that's being built) its super
    // class appears both in 'extends' and 'implements' clauses and whether any
    // interface appears multiple times in the 'implements' clause.
    // Moreover, it checks that `FutureOr` and `void` are not among the
    // supertypes and that `Enum` is not implemented by non-abstract classes.

    ClassHierarchyNode classHierarchyNode =
        hierarchyBuilder.getNodeFromClass(cls);
    if (libraryBuilder.libraryFeatures.enhancedEnums.isEnabled && !isEnum) {
      bool hasEnumSuperinterface = false;
      List<Supertype> interfaces = classHierarchyNode.superclasses;
      for (int i = 0; !hasEnumSuperinterface && i < interfaces.length; i++) {
        if (interfaces[i].classNode == enumClass) {
          hasEnumSuperinterface = true;
        }
      }
      interfaces = classHierarchyNode.interfaces;
      for (int i = 0; !hasEnumSuperinterface && i < interfaces.length; i++) {
        if (interfaces[i].classNode == enumClass) {
          hasEnumSuperinterface = true;
        }
      }
      if (!cls.isAbstract && !cls.isEnum && hasEnumSuperinterface) {
        addProblem(templateEnumSupertypeOfNonAbstractClass.withArguments(name),
            charOffset, noLength);
      }

      if (hasEnumSuperinterface && cls != underscoreEnumClass) {
        // Instance members named `values` are restricted.
        Builder? customValuesDeclaration =
            scope.lookupLocalMember("values", setter: false);
        if (customValuesDeclaration != null &&
            !customValuesDeclaration.isStatic) {
          // Retrieve the earliest declaration for error reporting.
          while (customValuesDeclaration?.next != null) {
            customValuesDeclaration = customValuesDeclaration?.next;
          }
          libraryBuilder.addProblem(
              templateEnumImplementerContainsValuesDeclaration
                  .withArguments(this.name),
              customValuesDeclaration!.charOffset,
              customValuesDeclaration.fullNameForErrors.length,
              fileUri);
        }
        customValuesDeclaration =
            scope.lookupLocalMember("values", setter: true);
        if (customValuesDeclaration != null &&
            !customValuesDeclaration.isStatic) {
          // Retrieve the earliest declaration for error reporting.
          while (customValuesDeclaration?.next != null) {
            customValuesDeclaration = customValuesDeclaration?.next;
          }
          libraryBuilder.addProblem(
              templateEnumImplementerContainsValuesDeclaration
                  .withArguments(this.name),
              customValuesDeclaration!.charOffset,
              customValuesDeclaration.fullNameForErrors.length,
              fileUri);
        }

        // Non-setter concrete instance members named `index` and hashCode and
        // operator == are restricted.
        for (String restrictedMemberName in const ["index", "hashCode", "=="]) {
          Builder? member =
              scope.lookupLocalMember(restrictedMemberName, setter: false);
          if (member is MemberBuilder && !member.isAbstract) {
            libraryBuilder.addProblem(
                templateEnumImplementerContainsRestrictedInstanceDeclaration
                    .withArguments(this.name, restrictedMemberName),
                member.charOffset,
                member.fullNameForErrors.length,
                fileUri);
          }
        }
      }
    }
    if (macroClass != null && !cls.isMacro && !cls.isAbstract) {
      // TODO(johnniwinther): Merge this check with the loop above.
      bool isMacroFound = false;
      List<Supertype> interfaces = classHierarchyNode.superclasses;
      for (int i = 0; !isMacroFound && i < interfaces.length; i++) {
        if (interfaces[i].classNode == macroClass) {
          isMacroFound = true;
        }
      }
      interfaces = classHierarchyNode.interfaces;
      for (int i = 0; !isMacroFound && i < interfaces.length; i++) {
        if (interfaces[i].classNode == macroClass) {
          isMacroFound = true;
        }
      }
      if (isMacroFound) {
        addProblem(templateMacroClassNotDeclaredMacro.withArguments(name),
            charOffset, noLength);
      }
    }

    void fail(NamedTypeBuilder target, Message message,
        TypeAliasBuilder? aliasBuilder) {
      int nameOffset = target.nameOffset;
      int nameLength = target.nameLength;
      if (aliasBuilder != null) {
        addProblem(message, nameOffset, nameLength, context: [
          messageTypedefCause.withLocation(
              aliasBuilder.fileUri, aliasBuilder.charOffset, noLength),
        ]);
      } else {
        addProblem(message, nameOffset, nameLength);
      }
    }

    // Extract and check superclass (if it exists).
    ClassBuilder? superClass;
    TypeBuilder? superClassType = supertypeBuilder;
    if (superClassType is NamedTypeBuilder) {
      TypeDeclarationBuilder? decl = superClassType.declaration;
      TypeAliasBuilder? aliasBuilder; // Non-null if a type alias is use.
      if (decl is TypeAliasBuilder) {
        aliasBuilder = decl;
        decl = aliasBuilder.unaliasDeclaration(superClassType.arguments,
            isUsedAsClass: true,
            usedAsClassCharOffset: superClassType.charOffset,
            usedAsClassFileUri: superClassType.fileUri);
      }
      // TODO(eernst): Should gather 'restricted supertype' checks in one place,
      // e.g., dynamic/int/String/Null and more are checked elsewhere.
      if (decl is VoidTypeDeclarationBuilder) {
        fail(superClassType, messageExtendsVoid, aliasBuilder);
      } else if (decl is NeverTypeDeclarationBuilder) {
        fail(superClassType, messageExtendsNever, aliasBuilder);
      } else if (decl is ClassBuilder) {
        superClass = decl;
      }
    }
    if (classHierarchyNode.isMixinApplication) {
      assert(mixedInTypeBuilder != null,
          "No mixed in type builder for mixin application $this.");
      ClassHierarchyNode mixedInNode = classHierarchyNode.mixedInNode!;
      ClassHierarchyNode? mixinSuperClassNode =
          mixedInNode.directSuperClassNode;
      if (mixinSuperClassNode != null &&
          mixinSuperClassNode.classBuilder.cls != objectClass &&
          !mixedInNode.classBuilder.cls.isMixinDeclaration) {
        addProblem(
            templateMixinInheritsFromNotObject
                .withArguments(mixedInNode.classBuilder.name),
            mixedInTypeBuilder!.charOffset ?? TreeNode.noOffset,
            noLength);
      }
    }

    if (interfaceBuilders == null) return;

    // Validate interfaces.
    Map<ClassBuilder, int>? problems;
    Map<ClassBuilder, int>? problemsOffsets;
    Set<ClassBuilder> implemented = new Set<ClassBuilder>();
    for (TypeBuilder type in interfaceBuilders!) {
      if (type is NamedTypeBuilder) {
        int? charOffset = type.charOffset;
        TypeDeclarationBuilder? typeDeclaration = type.declaration;
        TypeDeclarationBuilder? decl;
        TypeAliasBuilder? aliasBuilder; // Non-null if a type alias is used.
        if (typeDeclaration is TypeAliasBuilder) {
          aliasBuilder = typeDeclaration;
          decl = aliasBuilder.unaliasDeclaration(type.arguments,
              isUsedAsClass: true,
              usedAsClassCharOffset: type.charOffset,
              usedAsClassFileUri: type.fileUri);
        } else {
          decl = typeDeclaration;
        }
        if (decl is ClassBuilder) {
          ClassBuilder interface = decl;
          if (superClass == interface) {
            addProblem(
                templateImplementsSuperClass.withArguments(interface.name),
                this.charOffset,
                noLength);
          } else if (interface.cls.name == "FutureOr" &&
              interface.cls.enclosingLibrary.importUri.isScheme("dart") &&
              interface.cls.enclosingLibrary.importUri.path == "async") {
            addProblem(messageImplementsFutureOr, this.charOffset, noLength);
          } else if (implemented.contains(interface)) {
            // Aggregate repetitions.
            problems ??= <ClassBuilder, int>{};
            problems[interface] ??= 0;
            problems[interface] = problems[interface]! + 1;
            problemsOffsets ??= <ClassBuilder, int>{};
            problemsOffsets[interface] ??= charOffset ?? TreeNode.noOffset;
          } else {
            implemented.add(interface);
          }
        }
        if (decl != superClass) {
          // TODO(eernst): Have all 'restricted supertype' checks in one place.
          if (decl is VoidTypeDeclarationBuilder) {
            fail(type, messageImplementsVoid, aliasBuilder);
          } else if (decl is NeverTypeDeclarationBuilder) {
            fail(type, messageImplementsNever, aliasBuilder);
          }
        }
      }
    }
    if (problems != null) {
      problems.forEach((ClassBuilder interface, int repetitions) {
        addProblem(
            templateImplementsRepeated.withArguments(
                interface.name, repetitions),
            problemsOffsets![interface]!,
            noLength);
      });
    }
  }

  void checkMixinApplication(ClassHierarchy hierarchy, CoreTypes coreTypes) {
    TypeEnvironment typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
    // A mixin declaration can only be applied to a class that implements all
    // the declaration's superclass constraints.
    InterfaceType supertype = cls.supertype!.asInterfaceType;
    Substitution substitution = Substitution.fromSupertype(cls.mixedInType!);
    for (Supertype constraint in cls.mixedInClass!.onClause) {
      InterfaceType requiredInterface =
          substitution.substituteSupertype(constraint).asInterfaceType;
      InterfaceType? implementedInterface = hierarchy.getTypeAsInstanceOf(
          supertype, requiredInterface.classNode, libraryBuilder.library);
      if (implementedInterface == null ||
          !typeEnvironment.areMutualSubtypes(
              implementedInterface,
              requiredInterface,
              libraryBuilder.isNonNullableByDefault
                  ? SubtypeCheckMode.withNullabilities
                  : SubtypeCheckMode.ignoringNullabilities)) {
        libraryBuilder.addProblem(
            templateMixinApplicationIncompatibleSupertype.withArguments(
                supertype,
                requiredInterface,
                cls.mixedInType!.asInterfaceType,
                libraryBuilder.isNonNullableByDefault),
            cls.fileOffset,
            noLength,
            cls.fileUri);
      }
    }
  }

  // Computes the function type of a given redirection target. Returns [null] if
  // the type of the target could not be computed.
  FunctionType? _computeRedirecteeType(
      RedirectingFactoryBuilder factory, TypeEnvironment typeEnvironment) {
    ConstructorReferenceBuilder redirectionTarget = factory.redirectionTarget;
    Builder? targetBuilder = redirectionTarget.target;
    FunctionNode targetNode;
    if (targetBuilder == null) return null;
    if (targetBuilder is FunctionBuilder) {
      targetNode = targetBuilder.function;
    } else if (targetBuilder is AmbiguousBuilder) {
      // Multiple definitions with the same name: An error has already been
      // issued.
      // TODO(http://dartbug.com/35294): Unfortunate error; see also
      // https://dart-review.googlesource.com/c/sdk/+/85390/.
      return null;
    } else {
      unhandled("${redirectionTarget.target}", "computeRedirecteeType",
          charOffset, fileUri);
    }

    List<DartType>? typeArguments = factory.getTypeArguments();
    FunctionType targetFunctionType =
        targetNode.computeFunctionType(libraryBuilder.nonNullable);
    if (typeArguments != null &&
        targetFunctionType.typeParameters.length != typeArguments.length) {
      _addProblemForRedirectingFactory(
          factory,
          templateTypeArgumentMismatch
              .withArguments(targetFunctionType.typeParameters.length),
          redirectionTarget.charOffset,
          noLength);
      return null;
    }

    // Compute the substitution of the target class type parameters if
    // [redirectionTarget] has any type arguments.
    Substitution? substitution;
    bool hasProblem = false;
    if (typeArguments != null && typeArguments.length > 0) {
      substitution = Substitution.fromPairs(
          targetFunctionType.typeParameters, typeArguments);
      for (int i = 0; i < targetFunctionType.typeParameters.length; i++) {
        TypeParameter typeParameter = targetFunctionType.typeParameters[i];
        DartType typeParameterBound =
            substitution.substituteType(typeParameter.bound);
        DartType typeArgument = typeArguments[i];
        // Check whether the [typeArgument] respects the bounds of
        // [typeParameter].
        if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
            SubtypeCheckMode.ignoringNullabilities)) {
          _addProblemForRedirectingFactory(
              factory,
              templateRedirectingFactoryIncompatibleTypeArgument.withArguments(
                  typeArgument,
                  typeParameterBound,
                  libraryBuilder.isNonNullableByDefault),
              redirectionTarget.charOffset,
              noLength);
          hasProblem = true;
        } else if (libraryBuilder.isNonNullableByDefault) {
          if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
              SubtypeCheckMode.withNullabilities)) {
            _addProblemForRedirectingFactory(
                factory,
                templateRedirectingFactoryIncompatibleTypeArgument
                    .withArguments(typeArgument, typeParameterBound,
                        libraryBuilder.isNonNullableByDefault),
                redirectionTarget.charOffset,
                noLength);
            hasProblem = true;
          }
        }
      }
    } else if (typeArguments == null &&
        targetFunctionType.typeParameters.length > 0) {
      // TODO(hillerstrom): In this case, we need to perform type inference on
      // the redirectee to obtain actual type arguments which would allow the
      // following program to type check:
      //
      //    class A<T> {
      //       factory A() = B;
      //    }
      //    class B<T> implements A<T> {
      //       B();
      //    }
      //
      return null;
    }

    // Substitute if necessary.
    targetFunctionType = substitution == null
        ? targetFunctionType
        : (substitution.substituteType(targetFunctionType.withoutTypeParameters)
            as FunctionType);

    return hasProblem ? null : targetFunctionType;
  }

  bool _isCyclicRedirectingFactory(RedirectingFactoryBuilder factory) {
    // We use the [tortoise and hare algorithm]
    // (https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare) to
    // handle cycles.
    Builder? tortoise = factory;
    Builder? hare = factory.redirectionTarget.target;
    if (hare == factory) {
      return true;
    }
    while (tortoise != hare) {
      // Hare moves 2 steps forward.
      if (hare is! RedirectingFactoryBuilder) {
        return false;
      }
      hare = hare.redirectionTarget.target;
      if (hare == factory) {
        return true;
      }
      if (hare is! RedirectingFactoryBuilder) {
        return false;
      }
      hare = hare.redirectionTarget.target;
      if (hare == factory) {
        return true;
      }
      // Tortoise moves one step forward. No need to test type of tortoise
      // as it follows hare which already checked types.
      tortoise =
          (tortoise as RedirectingFactoryBuilder).redirectionTarget.target;
    }
    // Cycle found, but original factory doesn't belong to a cycle.
    return false;
  }

  void _addProblemForRedirectingFactory(RedirectingFactoryBuilder factory,
      Message message, int charOffset, int length) {
    addProblem(message, charOffset, length);
    String text = libraryBuilder.loader.target.context
        .format(
            message.withLocation(fileUri, charOffset, length), Severity.error)
        .plain;
    factory.body = new RedirectingFactoryBody.error(text);
  }

  void _checkRedirectingFactory(
      RedirectingFactoryBuilder factory, TypeEnvironment typeEnvironment) {
    // Check that factory declaration is not cyclic.
    if (_isCyclicRedirectingFactory(factory)) {
      _addProblemForRedirectingFactory(
          factory,
          templateCyclicRedirectingFactoryConstructors
              .withArguments("${factory.member.enclosingClass!.name}"
                  "${factory.name == '' ? '' : '.${factory.name}'}"),
          factory.charOffset,
          noLength);
      return;
    }

    // The factory type cannot contain any type parameters other than those of
    // its enclosing class, because constructors cannot specify type parameters
    // of their own.
    FunctionType factoryType = factory.function
        .computeThisFunctionType(libraryBuilder.nonNullable)
        .withoutTypeParameters;
    FunctionType? redirecteeType =
        _computeRedirecteeType(factory, typeEnvironment);

    // TODO(hillerstrom): It would be preferable to know whether a failure
    // happened during [_computeRedirecteeType].
    if (redirecteeType == null) {
      return;
    }

    // Redirection to generative enum constructors is forbidden and is reported
    // as an error elsewhere.
    if (!(cls.isEnum &&
        (factory.redirectionTarget.target?.isConstructor ?? false))) {
      // Check whether [redirecteeType] <: [factoryType].
      if (!typeEnvironment.isSubtypeOf(redirecteeType, factoryType,
          SubtypeCheckMode.ignoringNullabilities)) {
        _addProblemForRedirectingFactory(
            factory,
            templateIncompatibleRedirecteeFunctionType.withArguments(
                redirecteeType,
                factoryType,
                libraryBuilder.isNonNullableByDefault),
            factory.redirectionTarget.charOffset,
            noLength);
      } else if (libraryBuilder.isNonNullableByDefault) {
        if (!typeEnvironment.isSubtypeOf(
            redirecteeType, factoryType, SubtypeCheckMode.withNullabilities)) {
          _addProblemForRedirectingFactory(
              factory,
              templateIncompatibleRedirecteeFunctionType.withArguments(
                  redirecteeType,
                  factoryType,
                  libraryBuilder.isNonNullableByDefault),
              factory.redirectionTarget.charOffset,
              noLength);
        }
      }
    }
  }

  void checkRedirectingFactories(TypeEnvironment typeEnvironment) {
    Map<String, MemberBuilder> constructors = this.constructorScope.local;
    for (Builder? constructor in constructors.values) {
      do {
        if (constructor is RedirectingFactoryBuilder) {
          _checkRedirectingFactory(constructor, typeEnvironment);
        }
        constructor = constructor!.next;
      } while (constructor != null);
    }
  }

  Map<String, ConstructorRedirection>? _redirectingConstructors;

  /// Registers a constructor redirection for this class and returns true if
  /// this redirection gives rise to a cycle that has not been reported before.
  bool checkConstructorCyclic(String source, String target) {
    ConstructorRedirection? redirect = new ConstructorRedirection(target);
    _redirectingConstructors ??= <String, ConstructorRedirection>{};
    _redirectingConstructors![source] = redirect;
    while (redirect != null) {
      if (redirect.cycleReported) return false;
      if (redirect.target == source) {
        redirect.cycleReported = true;
        return true;
      }
      redirect = _redirectingConstructors![redirect.target];
    }
    return false;
  }

  TypeBuilder _checkSupertype(TypeBuilder supertype) {
    if (typeVariables == null) return supertype;
    Message? message;
    for (int i = 0; i < typeVariables!.length; ++i) {
      TypeVariableBuilder typeVariableBuilder = typeVariables![i];
      int variance = computeTypeVariableBuilderVariance(
          typeVariableBuilder, supertype, libraryBuilder);
      if (!Variance.greaterThanOrEqual(variance, typeVariables![i].variance)) {
        if (typeVariables![i].parameter.isLegacyCovariant) {
          message = templateInvalidTypeVariableInSupertype.withArguments(
              typeVariables![i].name,
              Variance.keywordString(variance),
              supertype.name as String);
        } else {
          message =
              templateInvalidTypeVariableInSupertypeWithVariance.withArguments(
                  Variance.keywordString(typeVariables![i].variance),
                  typeVariables![i].name,
                  Variance.keywordString(variance),
                  supertype.name as String);
        }
        libraryBuilder.addProblem(message, charOffset, noLength, fileUri);
      }
    }
    if (message != null) {
      return new NamedTypeBuilder(
          supertype.name as String, const NullabilityBuilder.omitted(),
          fileUri: fileUri,
          charOffset: charOffset,
          instanceTypeVariableAccess:
              InstanceTypeVariableAccessState.Unexpected)
        ..bind(
            libraryBuilder,
            new InvalidTypeDeclarationBuilder(supertype.name as String,
                message.withLocation(fileUri, charOffset, noLength)));
    }
    return supertype;
  }

  void checkVarianceInField(SourceFieldBuilder fieldBuilder,
      TypeEnvironment typeEnvironment, List<TypeParameter> typeParameters) {
    for (TypeParameter typeParameter in typeParameters) {
      int fieldVariance =
          computeVariance(typeParameter, fieldBuilder.fieldType);
      if (fieldBuilder.isClassInstanceMember) {
        reportVariancePositionIfInvalid(fieldVariance, typeParameter,
            fieldBuilder.fileUri, fieldBuilder.charOffset);
      }
      if (fieldBuilder.isClassInstanceMember &&
          fieldBuilder.isAssignable &&
          !fieldBuilder.isCovariantByDeclaration) {
        fieldVariance = Variance.combine(Variance.contravariant, fieldVariance);
        reportVariancePositionIfInvalid(fieldVariance, typeParameter,
            fieldBuilder.fileUri, fieldBuilder.charOffset);
      }
    }
  }

  void checkVarianceInFunction(Procedure procedure,
      TypeEnvironment typeEnvironment, List<TypeParameter> typeParameters) {
    List<TypeParameter> functionTypeParameters =
        procedure.function.typeParameters;
    List<VariableDeclaration> positionalParameters =
        procedure.function.positionalParameters;
    List<VariableDeclaration> namedParameters =
        procedure.function.namedParameters;
    DartType returnType = procedure.function.returnType;

    // ignore: unnecessary_null_comparison
    if (functionTypeParameters != null) {
      for (TypeParameter functionParameter in functionTypeParameters) {
        for (TypeParameter typeParameter in typeParameters) {
          int typeVariance = Variance.combine(Variance.invariant,
              computeVariance(typeParameter, functionParameter.bound));
          reportVariancePositionIfInvalid(typeVariance, typeParameter, fileUri,
              functionParameter.fileOffset);
        }
      }
    }
    // ignore: unnecessary_null_comparison
    if (positionalParameters != null) {
      for (VariableDeclaration formal in positionalParameters) {
        if (!formal.isCovariantByDeclaration) {
          for (TypeParameter typeParameter in typeParameters) {
            int formalVariance = Variance.combine(Variance.contravariant,
                computeVariance(typeParameter, formal.type));
            reportVariancePositionIfInvalid(
                formalVariance, typeParameter, fileUri, formal.fileOffset);
          }
        }
      }
    }
    // ignore: unnecessary_null_comparison
    if (namedParameters != null) {
      for (VariableDeclaration named in namedParameters) {
        for (TypeParameter typeParameter in typeParameters) {
          int namedVariance = Variance.combine(Variance.contravariant,
              computeVariance(typeParameter, named.type));
          reportVariancePositionIfInvalid(
              namedVariance, typeParameter, fileUri, named.fileOffset);
        }
      }
    }
    // ignore: unnecessary_null_comparison
    if (returnType != null) {
      for (TypeParameter typeParameter in typeParameters) {
        int returnTypeVariance = computeVariance(typeParameter, returnType);
        reportVariancePositionIfInvalid(returnTypeVariance, typeParameter,
            fileUri, procedure.function.fileOffset,
            isReturnType: true);
      }
    }
  }

  void reportVariancePositionIfInvalid(
      int variance, TypeParameter typeParameter, Uri fileUri, int fileOffset,
      {bool isReturnType: false}) {
    SourceLibraryBuilder library = this.libraryBuilder;
    if (!typeParameter.isLegacyCovariant &&
        !Variance.greaterThanOrEqual(variance, typeParameter.variance)) {
      Message message;
      if (isReturnType) {
        message = templateInvalidTypeVariableVariancePositionInReturnType
            .withArguments(Variance.keywordString(typeParameter.variance),
                typeParameter.name!, Variance.keywordString(variance));
      } else {
        message = templateInvalidTypeVariableVariancePosition.withArguments(
            Variance.keywordString(typeParameter.variance),
            typeParameter.name!,
            Variance.keywordString(variance));
      }
      library.reportTypeArgumentIssue(message, fileUri, fileOffset,
          typeParameter: typeParameter);
    }
  }

  void checkTypesInOutline(TypeEnvironment typeEnvironment) {
    forEach((String name, Builder builder) {
      if (builder is SourceMemberBuilder) {
        builder.checkVariance(this, typeEnvironment);
        builder.checkTypes(libraryBuilder, typeEnvironment);
      } else {
        assert(
            false,
            "Unexpected class member builder $builder "
            "(${builder.runtimeType})");
      }
    });

    forEachConstructor((String name, MemberBuilder builder) {
      if (builder is SourceMemberBuilder) {
        builder.checkTypes(libraryBuilder, typeEnvironment);
      } else {
        assert(false,
            "Unexpected constructor builder $builder (${builder.runtimeType})");
      }
    });
  }

  void addSyntheticConstructor(
      SyntheticSourceConstructorBuilder constructorBuilder) {
    String name = constructorBuilder.name;
    constructorBuilder.next = constructorScope.lookupLocalMember(name);
    constructorScope.addLocalMember(name, constructorBuilder);
    // Synthetic constructors are created after the component has been built
    // so we need to add the constructor to the class.
    cls.addConstructor(constructorBuilder.invokeTarget);
    if (constructorBuilder.readTarget != null &&
        constructorBuilder.readTarget != constructorBuilder.invokeTarget) {
      cls.addProcedure(constructorBuilder.readTarget as Procedure);
    }
    if (constructorBuilder.isConst) {
      cls.hasConstConstructor = true;
    }
  }

  int buildBodyNodes() {
    // TODO(ahe): restore file-offset once we track both origin and patch file
    // URIs. See https://github.com/dart-lang/sdk/issues/31579
    if (isPatch) {
      cls.annotations.forEach((m) => m.fileOffset = origin.cls.fileOffset);
    }

    int count = 0;

    void buildMembers(Builder builder) {
      if (builder.parent != this) {
        return;
      }
      if (builder is SourceMemberBuilder) {
        count += builder.buildBodyNodes((Member member, BuiltMemberKind kind) {
          _buildMember(builder, member, kind);
        });
      }
    }

    scope
        .filteredIterator(
            parent: this, includeDuplicates: true, includeAugmentations: true)
        .forEach(buildMembers);
    constructorScope
        .filteredIterator(
            parent: this, includeDuplicates: true, includeAugmentations: true)
        .forEach(buildMembers);
    return count;
  }

  void _buildMember(SourceMemberBuilder memberBuilder, Member member,
      BuiltMemberKind memberKind) {
    member.parent = cls;
    if (!memberBuilder.isDuplicate &&
        !memberBuilder.isConflictingSetter &&
        !memberBuilder.isConflictingAugmentationMember) {
      if (member is Procedure) {
        cls.addProcedure(member);
      } else if (member is Field) {
        cls.addField(member);
      } else if (member is Constructor) {
        cls.addConstructor(member);
      } else if (member is RedirectingFactory) {
        cls.addRedirectingFactory(member);
      } else {
        unhandled("${member.runtimeType}", "getMember", member.fileOffset,
            member.fileUri);
      }
    }
  }

  /// Return a map whose keys are the supertypes of this [SourceClassBuilder]
  /// after expansion of type aliases, if any. For each supertype key, the
  /// corresponding value is the type alias which was unaliased in order to
  /// find the supertype, or null if the supertype was not aliased.
  Map<TypeDeclarationBuilder?, TypeAliasBuilder?> computeDirectSupertypes(
      ClassBuilder objectClass) {
    final Map<TypeDeclarationBuilder?, TypeAliasBuilder?> result = {};
    final TypeBuilder? supertype = this.supertypeBuilder;
    if (supertype != null) {
      TypeDeclarationBuilder? declarationBuilder = supertype.declaration;
      if (declarationBuilder is TypeAliasBuilder) {
        TypeAliasBuilder aliasBuilder = declarationBuilder;
        NamedTypeBuilder namedBuilder = supertype as NamedTypeBuilder;
        declarationBuilder = aliasBuilder.unaliasDeclaration(
            namedBuilder.arguments,
            isUsedAsClass: true,
            usedAsClassCharOffset: namedBuilder.charOffset,
            usedAsClassFileUri: namedBuilder.fileUri);
        result[declarationBuilder] = aliasBuilder;
      } else {
        result[declarationBuilder] = null;
      }
    } else if (objectClass != this) {
      result[objectClass] = null;
    }
    final List<TypeBuilder>? interfaces = this.interfaceBuilders;
    if (interfaces != null) {
      for (int i = 0; i < interfaces.length; i++) {
        TypeBuilder interface = interfaces[i];
        TypeDeclarationBuilder? declarationBuilder = interface.declaration;
        if (declarationBuilder is TypeAliasBuilder) {
          TypeAliasBuilder aliasBuilder = declarationBuilder;
          NamedTypeBuilder namedBuilder = interface as NamedTypeBuilder;
          declarationBuilder = aliasBuilder.unaliasDeclaration(
              namedBuilder.arguments,
              isUsedAsClass: true,
              usedAsClassCharOffset: namedBuilder.charOffset,
              usedAsClassFileUri: namedBuilder.fileUri);
          result[declarationBuilder] = aliasBuilder;
        } else {
          result[declarationBuilder] = null;
        }
      }
    }
    final TypeBuilder? mixedInTypeBuilder = this.mixedInTypeBuilder;
    if (mixedInTypeBuilder != null) {
      TypeDeclarationBuilder? declarationBuilder =
          mixedInTypeBuilder.declaration;
      if (declarationBuilder is TypeAliasBuilder) {
        TypeAliasBuilder aliasBuilder = declarationBuilder;
        NamedTypeBuilder namedBuilder = mixedInTypeBuilder as NamedTypeBuilder;
        declarationBuilder = aliasBuilder.unaliasDeclaration(
            namedBuilder.arguments,
            isUsedAsClass: true,
            usedAsClassCharOffset: namedBuilder.charOffset,
            usedAsClassFileUri: namedBuilder.fileUri);
        result[declarationBuilder] = aliasBuilder;
      } else {
        result[declarationBuilder] = null;
      }
    }
    return result;
  }

  @override
  int compareTo(SourceClassBuilder other) {
    int result = "$fileUri".compareTo("${other.fileUri}");
    if (result != 0) return result;
    return charOffset.compareTo(other.charOffset);
  }

  bool _hasUserDefinedNoSuchMethod(
      Class klass, ClassHierarchy hierarchy, Class objectClass) {
    Member? noSuchMethod = hierarchy.getDispatchTarget(klass, noSuchMethodName);
    return noSuchMethod != null && noSuchMethod.enclosingClass != objectClass;
  }

  List<Member> _getStaticMembers() {
    List<Member> staticMembers = <Member>[];
    for (Field field in cls.fields) {
      if (field.isStatic) {
        staticMembers.add(field);
      }
    }
    for (Procedure procedure in cls.procedures) {
      if (procedure.isStatic) {
        staticMembers.add(procedure);
      }
    }
    staticMembers.sort(ClassHierarchy.compareMembers);
    return staticMembers;
  }

  bool _addMissingNoSuchMethodForwarders(
      KernelTarget target, Set<Member> existingForwarders,
      {required bool forSetters}) {
    // ignore: unnecessary_null_comparison
    assert(forSetters != null);

    ClassHierarchy hierarchy = target.loader.hierarchy;

    List<Member> allMembers =
        hierarchy.getInterfaceMembers(cls, setters: forSetters);
    List<Member> concreteMembers =
        hierarchy.getDispatchTargets(cls, setters: forSetters);
    List<Member> declaredMembers =
        hierarchy.getDeclaredMembers(cls, setters: forSetters);
    List<Member> staticMembers = _getStaticMembers();

    Procedure noSuchMethod = ClassHierarchy.findMemberByName(
        hierarchy.getInterfaceMembers(cls), noSuchMethodName) as Procedure;
    bool clsHasUserDefinedNoSuchMethod =
        _hasUserDefinedNoSuchMethod(cls, hierarchy, target.objectClass);

    bool changed = false;

    // It's possible to have multiple abstract members with the same name -- as
    // long as there's one with function type that's a subtype of function types
    // of all other members.  Such member is called "best" in the code below.
    // Members with the same name are put into groups, and "best" is searched
    // for in each group.
    Map<Name, List<Member>> sameNameMembers = {};
    for (Member member in allMembers) {
      (sameNameMembers[member.name] ??= []).add(member);
    }
    for (MapEntry<Name, List<Member>> entry in sameNameMembers.entries) {
      List<Member> members = entry.value;
      assert(members.isNotEmpty);
      CombinedMemberSignatureBuilder combinedMemberSignature =
          new CombinedMemberSignatureBuilder(hierarchy, this, members,
              forSetter: forSetters);
      Member? member = combinedMemberSignature.canonicalMember;
      if (member != null) {
        if (_isForwarderRequired(clsHasUserDefinedNoSuchMethod, member, cls,
                concreteMembers, staticMembers,
                isPatch: member.fileUri != member.enclosingClass!.fileUri) &&
            !existingForwarders.contains(member)) {
          assert(!combinedMemberSignature.needsCovarianceMerging,
              "Needed covariant merging for ${members}");
          if (ClassHierarchy.findMemberByName(declaredMembers, member.name) !=
              null) {
            _transformProcedureToNoSuchMethodForwarder(
                noSuchMethod, target, member as Procedure);
          } else {
            Procedure memberSignature =
                combinedMemberSignature.createMemberFromSignature()!;
            _transformProcedureToNoSuchMethodForwarder(
                noSuchMethod, target, memberSignature);
            cls.procedures.add(memberSignature);
            memberSignature.parent = cls;

            if (member is Procedure) {
              libraryBuilder.forwardersOrigins.add(memberSignature);
              libraryBuilder.forwardersOrigins.add(member);
            }
          }
          changed = true;
        }
      }
    }

    return changed;
  }

  /// Adds noSuchMethod forwarding stubs to this class.
  ///
  /// Returns `true` if the class was modified.
  bool addNoSuchMethodForwarders(
      KernelTarget target, ClassHierarchy hierarchy) {
    // Don't install forwarders in superclasses.
    if (cls.isAbstract) return false;

    // Compute signatures of existing noSuchMethod forwarders in superclasses.
    Set<Member> existingForwarders = new Set<Member>.identity();
    Set<Member> existingSetterForwarders = new Set<Member>.identity();
    {
      Class? nearestConcreteSuperclass = cls.superclass;
      while (nearestConcreteSuperclass != null &&
          nearestConcreteSuperclass.isAbstract) {
        nearestConcreteSuperclass = nearestConcreteSuperclass.superclass;
      }
      if (nearestConcreteSuperclass != null) {
        bool superHasUserDefinedNoSuchMethod = _hasUserDefinedNoSuchMethod(
            nearestConcreteSuperclass, hierarchy, target.objectClass);
        {
          List<Member> concreteMembers =
              hierarchy.getDispatchTargets(nearestConcreteSuperclass);
          List<Member> staticMembers = _getStaticMembers();
          for (Member member
              in hierarchy.getInterfaceMembers(nearestConcreteSuperclass)) {
            if (_isForwarderRequired(superHasUserDefinedNoSuchMethod, member,
                nearestConcreteSuperclass, concreteMembers, staticMembers,
                isPatch: member.fileUri != member.enclosingClass!.fileUri)) {
              existingForwarders.add(member);
            }
          }
        }

        {
          List<Member> concreteSetters = hierarchy
              .getDispatchTargets(nearestConcreteSuperclass, setters: true);
          List<Member> staticSetters = _getStaticMembers();
          for (Member member in hierarchy
              .getInterfaceMembers(nearestConcreteSuperclass, setters: true)) {
            if (_isForwarderRequired(superHasUserDefinedNoSuchMethod, member,
                nearestConcreteSuperclass, concreteSetters, staticSetters)) {
              existingSetterForwarders.add(member);
            }
          }
        }
      }
    }

    bool changed = false;

    // Install noSuchMethod forwarders for methods and getters.
    changed = _addMissingNoSuchMethodForwarders(target, existingForwarders,
            forSetters: false) ||
        changed;

    // Install noSuchMethod forwarders for setters.
    changed = _addMissingNoSuchMethodForwarders(
            target, existingSetterForwarders,
            forSetters: true) ||
        changed;

    return changed;
  }

  /// Tells if a noSuchMethod forwarder is required for [member] in [cls].
  bool _isForwarderRequired(bool hasUserDefinedNoSuchMethod, Member member,
      Class cls, List<Member> concreteMembers, List<Member> staticMembers,
      {bool isPatch = false}) {
    // A noSuchMethod forwarder is allowed for an abstract member if the class
    // has a user-defined noSuchMethod or if the member is private and is
    // defined in a different library.  Private members in patches are assumed
    // to be visible only to patches, so they are treated as if they were from
    // another library.
    bool isForwarderAllowed = hasUserDefinedNoSuchMethod ||
        (member.name.isPrivate &&
            cls.enclosingLibrary.compareTo(member.enclosingLibrary) != 0) ||
        (member.name.isPrivate && isPatch);
    // A noSuchMethod forwarder is required if it's allowed and if there's no
    // concrete implementation or a forwarder already.
    bool isForwarderRequired = isForwarderAllowed &&
        ClassHierarchy.findMemberByName(concreteMembers, member.name) == null &&
        ClassHierarchy.findMemberByName(staticMembers, member.name) == null;
    return isForwarderRequired;
  }

  void _transformProcedureToNoSuchMethodForwarder(
      Procedure noSuchMethodInterface,
      KernelTarget target,
      Procedure procedure) {
    String prefix = procedure.isGetter
        ? 'get:'
        : procedure.isSetter
            ? 'set:'
            : '';
    String invocationName = prefix + procedure.name.text;
    if (procedure.isSetter) invocationName += '=';
    Expression invocation = target.backendTarget.instantiateInvocation(
        target.loader.coreTypes,
        new ThisExpression(),
        invocationName,
        new Arguments.forwarded(procedure.function, libraryBuilder.library),
        procedure.fileOffset,
        /*isSuper=*/ false);
    Expression result = new InstanceInvocation(InstanceAccessKind.Instance,
        new ThisExpression(), noSuchMethodName, new Arguments([invocation]),
        functionType: noSuchMethodInterface.getterType as FunctionType,
        interfaceTarget: noSuchMethodInterface)
      ..fileOffset = procedure.fileOffset;
    if (procedure.function.returnType is! VoidType) {
      result = new AsExpression(result, procedure.function.returnType)
        ..isTypeError = true
        ..isForDynamic = true
        ..isForNonNullableByDefault = libraryBuilder.isNonNullableByDefault
        ..fileOffset = procedure.fileOffset;
    }
    procedure.function.body = new ReturnStatement(result)
      ..fileOffset = procedure.fileOffset
      ..parent = procedure.function;
    procedure.function.asyncMarker = AsyncMarker.Sync;
    procedure.function.dartAsyncMarker = AsyncMarker.Sync;

    procedure.isAbstract = false;
    procedure.stubKind = ProcedureStubKind.NoSuchMethodForwarder;
    procedure.stubTarget = null;
  }

  void _addRedirectingConstructor(
      SourceFactoryBuilder constructorBuilder,
      SourceLibraryBuilder library,
      Reference? fieldReference,
      Reference? getterReference) {
    // Add a new synthetic field to this class for representing factory
    // constructors. This is used to support resolving such constructors in
    // source code.
    //
    // The synthetic field looks like this:
    //
    //     final _redirecting# = [c1, ..., cn];
    //
    // Where each c1 ... cn are an instance of [StaticGet] whose target is
    // [constructor.target].
    //
    // TODO(ahe): Add a kernel node to represent redirecting factory bodies.
    _RedirectingConstructorsFieldBuilder? constructorsField =
        origin.scope.lookupLocalMember(redirectingName, setter: false)
            as _RedirectingConstructorsFieldBuilder?;
    if (constructorsField == null) {
      ListLiteral literal = new ListLiteral(<Expression>[]);
      Name name = new Name(redirectingName, library.library);
      Field field = new Field.immutable(name,
          isStatic: true,
          isFinal: true,
          initializer: literal,
          fileUri: cls.fileUri,
          fieldReference: fieldReference,
          getterReference: getterReference)
        ..fileOffset = cls.fileOffset;
      cls.addField(field);
      constructorsField = new _RedirectingConstructorsFieldBuilder(field, this);
      origin.scope
          .addLocalMember(redirectingName, constructorsField, setter: false);
    }
    Field field = constructorsField.field;
    ListLiteral literal = field.initializer as ListLiteral;
    literal.expressions.add(
        new ConstructorTearOff(constructorBuilder.member)..parent = literal);
  }

  int resolveConstructors(SourceLibraryBuilder library) {
    if (constructorReferences == null) return 0;
    for (ConstructorReferenceBuilder ref in constructorReferences!) {
      ref.resolveIn(scope, library);
    }
    int count = constructorReferences!.length;
    if (count != 0) {
      Map<String, MemberBuilder> constructors = this.constructorScope.local;
      // Copy keys to avoid concurrent modification error.
      for (MapEntry<String, MemberBuilder> entry in constructors.entries) {
        Builder? declaration = entry.value;
        while (declaration != null) {
          if (declaration.parent != this) {
            unexpected("$fileUri", "${declaration.parent!.fileUri}", charOffset,
                fileUri);
          }
          if (declaration is RedirectingFactoryBuilder) {
            // Compute the immediate redirection target, not the effective.

            ConstructorReferenceBuilder redirectionTarget =
                declaration.redirectionTarget;
            List<TypeBuilder>? typeArguments = redirectionTarget.typeArguments;
            Builder? target = redirectionTarget.target;
            if (typeArguments != null && target is MemberBuilder) {
              Object? redirectionTargetName = redirectionTarget.name;
              if (redirectionTargetName is String) {
                // Do nothing. This is the case of an identifier followed by
                // type arguments, such as the following:
                //   B<T>
                //   B<T>.named
              } else if (redirectionTargetName is QualifiedName) {
                if (target.name.isEmpty) {
                  // Do nothing. This is the case of a qualified
                  // non-constructor prefix (for example, with a library
                  // qualifier) followed by type arguments, such as the
                  // following:
                  //   lib.B<T>
                } else if (target.name != redirectionTargetName.suffix.lexeme) {
                  // Do nothing. This is the case of a qualified
                  // non-constructor prefix followed by type arguments followed
                  // by a constructor name, such as the following:
                  //   lib.B<T>.named
                } else {
                  // TODO(cstefantsova,johnniwinther): Handle this in case in
                  // ConstructorReferenceBuilder.resolveIn and unify with other
                  // cases of handling of type arguments after constructor
                  // names.
                  addProblem(
                      messageConstructorWithTypeArguments,
                      redirectionTargetName.charOffset,
                      redirectionTargetName.name.length);
                }
              }
            }

            // ignore: unnecessary_null_comparison
            if (redirectionTarget != null) {
              Builder? targetBuilder = redirectionTarget.target;
              if (declaration.next == null) {
                // Only the first one (that is, the last on in the linked list)
                // is actually in the kernel tree. This call creates a StaticGet
                // to [declaration.target] in a field `_redirecting#` which is
                // only legal to do to things in the kernel tree.
                Reference? fieldReference;
                Reference? getterReference;
                if (referencesFromIndexed != null) {
                  Name name =
                      new Name(redirectingName, referencesFromIndexed!.library);
                  fieldReference =
                      referencesFromIndexed!.lookupFieldReference(name);
                  getterReference =
                      referencesFromIndexed!.lookupGetterReference(name);
                }
                _addRedirectingConstructor(
                    declaration, library, fieldReference, getterReference);
              }
              Member? targetNode;
              if (targetBuilder is FunctionBuilder) {
                targetNode = targetBuilder.member;
              } else if (targetBuilder is DillMemberBuilder) {
                targetNode = targetBuilder.member;
              } else if (targetBuilder is AmbiguousBuilder) {
                _addProblemForRedirectingFactory(
                    declaration,
                    templateDuplicatedDeclarationUse
                        .withArguments(redirectionTarget.fullNameForErrors),
                    redirectionTarget.charOffset,
                    noLength);
              } else {
                _addProblemForRedirectingFactory(
                    declaration,
                    templateRedirectionTargetNotFound
                        .withArguments(redirectionTarget.fullNameForErrors),
                    redirectionTarget.charOffset,
                    noLength);
              }
              if (targetNode != null &&
                  targetNode is Constructor &&
                  targetNode.enclosingClass.isAbstract) {
                _addProblemForRedirectingFactory(
                    declaration,
                    templateAbstractRedirectedClassInstantiation
                        .withArguments(redirectionTarget.fullNameForErrors),
                    redirectionTarget.charOffset,
                    noLength);
                targetNode = null;
              }
              if (targetNode != null &&
                  targetNode is Constructor &&
                  targetNode.enclosingClass.isEnum) {
                _addProblemForRedirectingFactory(
                    declaration,
                    messageEnumFactoryRedirectsToConstructor,
                    redirectionTarget.charOffset,
                    noLength);
                targetNode = null;
              }
              if (targetNode != null) {
                List<DartType> typeArguments = declaration.typeArguments ??
                    new List<DartType>.filled(
                        targetNode.enclosingClass!.typeParameters.length,
                        const UnknownType());
                declaration.setRedirectingFactoryBody(
                    targetNode, typeArguments);
              }
            }
          }
          declaration = declaration.next;
        }
      }
    }
    return count;
  }

  void _handleSeenCovariant(
      ClassHierarchyMembers memberHierarchy,
      Member interfaceMember,
      bool isSetter,
      callback(Member interfaceMember, bool isSetter)) {
    // When a parameter is covariant we have to check that we also
    // override the same member in all parents.
    for (Supertype supertype in interfaceMember.enclosingClass!.supers) {
      Member? member = memberHierarchy.getInterfaceMember(
          supertype.classNode, interfaceMember.name,
          setter: isSetter);
      if (member != null) {
        callback(member, isSetter);
      }
    }
  }

  void checkOverride(
      Types types,
      ClassHierarchyMembers memberHierarchy,
      Member declaredMember,
      Member interfaceMember,
      bool isSetter,
      callback(Member interfaceMember, bool isSetter),
      {required bool isInterfaceCheck,
      required bool declaredNeedsLegacyErasure}) {
    // ignore: unnecessary_null_comparison
    assert(isInterfaceCheck != null);
    // ignore: unnecessary_null_comparison
    assert(declaredNeedsLegacyErasure != null);
    if (declaredMember == interfaceMember) {
      return;
    }
    Member interfaceMemberOrigin =
        interfaceMember.memberSignatureOrigin ?? interfaceMember;
    if (declaredMember is Constructor || interfaceMember is Constructor) {
      unimplemented(
          "Constructor in override check.", declaredMember.fileOffset, fileUri);
    }
    if (declaredMember is Procedure && interfaceMember is Procedure) {
      if (declaredMember.kind == interfaceMember.kind) {
        if (declaredMember.kind == ProcedureKind.Method ||
            declaredMember.kind == ProcedureKind.Operator) {
          bool seenCovariant = checkMethodOverride(
              types,
              declaredMember,
              interfaceMember,
              interfaceMemberOrigin,
              isInterfaceCheck,
              declaredNeedsLegacyErasure);
          if (seenCovariant) {
            _handleSeenCovariant(
                memberHierarchy, interfaceMember, isSetter, callback);
          }
        } else if (declaredMember.kind == ProcedureKind.Getter) {
          checkGetterOverride(
              types,
              declaredMember,
              interfaceMember,
              interfaceMemberOrigin,
              isInterfaceCheck,
              declaredNeedsLegacyErasure);
        } else if (declaredMember.kind == ProcedureKind.Setter) {
          bool seenCovariant = checkSetterOverride(
              types,
              declaredMember,
              interfaceMember,
              interfaceMemberOrigin,
              isInterfaceCheck,
              declaredNeedsLegacyErasure);
          if (seenCovariant) {
            _handleSeenCovariant(
                memberHierarchy, interfaceMember, isSetter, callback);
          }
        } else {
          assert(
              false,
              "Unexpected procedure kind in override check: "
              "${declaredMember.kind}");
        }
      }
    } else {
      bool declaredMemberHasGetter = declaredMember is Field ||
          declaredMember is Procedure && declaredMember.isGetter;
      bool interfaceMemberHasGetter = interfaceMember is Field ||
          interfaceMember is Procedure && interfaceMember.isGetter;
      bool declaredMemberHasSetter = (declaredMember is Field &&
              !declaredMember.isFinal &&
              !declaredMember.isConst) ||
          declaredMember is Procedure && declaredMember.isSetter;
      bool interfaceMemberHasSetter = (interfaceMember is Field &&
              !interfaceMember.isFinal &&
              !interfaceMember.isConst) ||
          interfaceMember is Procedure && interfaceMember.isSetter;
      if (declaredMemberHasGetter && interfaceMemberHasGetter) {
        checkGetterOverride(
            types,
            declaredMember,
            interfaceMember,
            interfaceMemberOrigin,
            isInterfaceCheck,
            declaredNeedsLegacyErasure);
      }
      if (declaredMemberHasSetter && interfaceMemberHasSetter) {
        bool seenCovariant = checkSetterOverride(
            types,
            declaredMember,
            interfaceMember,
            interfaceMemberOrigin,
            isInterfaceCheck,
            declaredNeedsLegacyErasure);
        if (seenCovariant) {
          _handleSeenCovariant(
              memberHierarchy, interfaceMember, isSetter, callback);
        }
      }
    }
    // TODO(ahe): Handle other cases: accessors, operators, and fields.
  }

  void checkGetterSetter(Types types, Member getter, Member setter) {
    if (getter == setter) {
      return;
    }
    if (cls != getter.enclosingClass &&
        getter.enclosingClass == setter.enclosingClass) {
      return;
    }

    DartType getterType = getter.getterType;
    if (getter.enclosingClass!.typeParameters.isNotEmpty) {
      getterType = Substitution.fromPairs(
              getter.enclosingClass!.typeParameters,
              types.hierarchy.getTypeArgumentsAsInstanceOf(
                  thisType, getter.enclosingClass!)!)
          .substituteType(getterType);
    }

    DartType setterType = setter.setterType;
    if (setter.enclosingClass!.typeParameters.isNotEmpty) {
      setterType = Substitution.fromPairs(
              setter.enclosingClass!.typeParameters,
              types.hierarchy.getTypeArgumentsAsInstanceOf(
                  thisType, setter.enclosingClass!)!)
          .substituteType(setterType);
    }

    if (getterType is InvalidType || setterType is InvalidType) {
      // Don't report a problem as something else is wrong that has already
      // been reported.
    } else {
      bool isValid = types.isSubtypeOf(
          getterType,
          setterType,
          libraryBuilder.isNonNullableByDefault
              ? SubtypeCheckMode.withNullabilities
              : SubtypeCheckMode.ignoringNullabilities);
      if (!isValid && !libraryBuilder.isNonNullableByDefault) {
        // Allow assignability in legacy libraries.
        isValid = types.isSubtypeOf(
            setterType, getterType, SubtypeCheckMode.ignoringNullabilities);
      }
      if (!isValid) {
        Member getterOrigin = getter.memberSignatureOrigin ?? getter;
        Member setterOrigin = setter.memberSignatureOrigin ?? setter;
        String getterMemberName = '${getterOrigin.enclosingClass!.name}'
            '.${getterOrigin.name.text}';
        String setterMemberName = '${setterOrigin.enclosingClass!.name}'
            '.${setterOrigin.name.text}';
        if (getterOrigin.enclosingClass == cls &&
            setterOrigin.enclosingClass == cls) {
          Template<Message Function(DartType, String, DartType, String, bool)>
              template = libraryBuilder.isNonNullableByDefault
                  ? templateInvalidGetterSetterType
                  : templateInvalidGetterSetterTypeLegacy;
          libraryBuilder.addProblem(
              template.withArguments(getterType, getterMemberName, setterType,
                  setterMemberName, libraryBuilder.isNonNullableByDefault),
              getterOrigin.fileOffset,
              getterOrigin.name.text.length,
              getterOrigin.fileUri,
              context: [
                templateInvalidGetterSetterTypeSetterContext
                    .withArguments(setterMemberName)
                    .withLocation(setterOrigin.fileUri, setterOrigin.fileOffset,
                        setterOrigin.name.text.length)
              ]);
        } else if (getterOrigin.enclosingClass == cls) {
          Template<Message Function(DartType, String, DartType, String, bool)>
              template = libraryBuilder.isNonNullableByDefault
                  ? templateInvalidGetterSetterTypeSetterInheritedGetter
                  : templateInvalidGetterSetterTypeSetterInheritedGetterLegacy;
          if (getterOrigin is Field) {
            template = libraryBuilder.isNonNullableByDefault
                ? templateInvalidGetterSetterTypeSetterInheritedField
                : templateInvalidGetterSetterTypeSetterInheritedFieldLegacy;
          }
          libraryBuilder.addProblem(
              template.withArguments(getterType, getterMemberName, setterType,
                  setterMemberName, libraryBuilder.isNonNullableByDefault),
              getterOrigin.fileOffset,
              getterOrigin.name.text.length,
              getterOrigin.fileUri,
              context: [
                templateInvalidGetterSetterTypeSetterContext
                    .withArguments(setterMemberName)
                    .withLocation(setterOrigin.fileUri, setterOrigin.fileOffset,
                        setterOrigin.name.text.length)
              ]);
        } else if (setterOrigin.enclosingClass == cls) {
          Template<Message Function(DartType, String, DartType, String, bool)>
              template = libraryBuilder.isNonNullableByDefault
                  ? templateInvalidGetterSetterTypeGetterInherited
                  : templateInvalidGetterSetterTypeGetterInheritedLegacy;
          Template<Message Function(String)> context =
              templateInvalidGetterSetterTypeGetterContext;
          if (getterOrigin is Field) {
            template = libraryBuilder.isNonNullableByDefault
                ? templateInvalidGetterSetterTypeFieldInherited
                : templateInvalidGetterSetterTypeFieldInheritedLegacy;
            context = templateInvalidGetterSetterTypeFieldContext;
          }
          libraryBuilder.addProblem(
              template.withArguments(getterType, getterMemberName, setterType,
                  setterMemberName, libraryBuilder.isNonNullableByDefault),
              setterOrigin.fileOffset,
              setterOrigin.name.text.length,
              setterOrigin.fileUri,
              context: [
                context.withArguments(getterMemberName).withLocation(
                    getterOrigin.fileUri,
                    getterOrigin.fileOffset,
                    getterOrigin.name.text.length)
              ]);
        } else {
          Template<Message Function(DartType, String, DartType, String, bool)>
              template = libraryBuilder.isNonNullableByDefault
                  ? templateInvalidGetterSetterTypeBothInheritedGetter
                  : templateInvalidGetterSetterTypeBothInheritedGetterLegacy;
          Template<Message Function(String)> context =
              templateInvalidGetterSetterTypeGetterContext;
          if (getterOrigin is Field) {
            template = libraryBuilder.isNonNullableByDefault
                ? templateInvalidGetterSetterTypeBothInheritedField
                : templateInvalidGetterSetterTypeBothInheritedFieldLegacy;
            context = templateInvalidGetterSetterTypeFieldContext;
          }
          libraryBuilder.addProblem(
              template.withArguments(getterType, getterMemberName, setterType,
                  setterMemberName, libraryBuilder.isNonNullableByDefault),
              charOffset,
              noLength,
              fileUri,
              context: [
                context.withArguments(getterMemberName).withLocation(
                    getterOrigin.fileUri,
                    getterOrigin.fileOffset,
                    getterOrigin.name.text.length),
                templateInvalidGetterSetterTypeSetterContext
                    .withArguments(setterMemberName)
                    .withLocation(setterOrigin.fileUri, setterOrigin.fileOffset,
                        setterOrigin.name.text.length)
              ]);
        }
      }
    }
  }

  Uri _getMemberUri(Member member) {
    if (member is Field) return member.fileUri;
    if (member is Procedure) return member.fileUri;
    // Other member types won't be seen because constructors don't participate
    // in override relationships
    return unhandled('${member.runtimeType}', '_getMemberUri', -1, null);
  }

  Substitution? _computeInterfaceSubstitution(
      Types types,
      Member declaredMember,
      Member interfaceMember,
      Member interfaceMemberOrigin,
      FunctionNode? declaredFunction,
      FunctionNode? interfaceFunction,
      bool isInterfaceCheck,
      bool declaredNeedsLegacyErasure) {
    Substitution? interfaceSubstitution;
    if (interfaceMember.enclosingClass!.typeParameters.isNotEmpty) {
      Class enclosingClass = interfaceMember.enclosingClass!;
      interfaceSubstitution = Substitution.fromPairs(
          enclosingClass.typeParameters,
          types.hierarchy
              .getTypeArgumentsAsInstanceOf(thisType, enclosingClass)!);
    }

    if (declaredFunction?.typeParameters.length !=
        interfaceFunction?.typeParameters.length) {
      reportInvalidOverride(
          isInterfaceCheck,
          declaredMember,
          templateOverrideTypeVariablesMismatch.withArguments(
              "${declaredMember.enclosingClass!.name}."
                  "${declaredMember.name.text}",
              "${interfaceMemberOrigin.enclosingClass!.name}."
                  "${interfaceMemberOrigin.name.text}"),
          declaredMember.fileOffset,
          noLength,
          context: [
            templateOverriddenMethodCause
                .withArguments(interfaceMemberOrigin.name.text)
                .withLocation(_getMemberUri(interfaceMemberOrigin),
                    interfaceMemberOrigin.fileOffset, noLength)
          ]);
    } else if (declaredFunction?.typeParameters != null) {
      Map<TypeParameter, DartType> substitutionMap =
          <TypeParameter, DartType>{};

      // Since the bound of `interfaceFunction!.parameter[i]` may have changed
      // during substitution, it can affect the nullabilities of the types in
      // the substitution map. The first parameter to
      // [TypeParameterType.forAlphaRenaming] should be updated to account for
      // the change.
      List<TypeParameter> interfaceTypeParameters;
      if (interfaceSubstitution == null) {
        interfaceTypeParameters = interfaceFunction!.typeParameters;
      } else {
        FreshTypeParameters freshTypeParameters =
            getFreshTypeParameters(interfaceFunction!.typeParameters);
        interfaceTypeParameters = freshTypeParameters.freshTypeParameters;
        for (TypeParameter parameter in interfaceTypeParameters) {
          parameter.bound =
              interfaceSubstitution.substituteType(parameter.bound);
        }
        updateBoundNullabilities(interfaceTypeParameters);
      }
      for (int i = 0; i < declaredFunction!.typeParameters.length; ++i) {
        substitutionMap[interfaceFunction.typeParameters[i]] =
            new TypeParameterType.forAlphaRenaming(
                interfaceTypeParameters[i], declaredFunction.typeParameters[i]);
      }
      Substitution substitution = Substitution.fromMap(substitutionMap);
      for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
        TypeParameter declaredParameter = declaredFunction.typeParameters[i];
        TypeParameter interfaceParameter = interfaceFunction.typeParameters[i];
        if (!interfaceParameter.isCovariantByClass) {
          DartType declaredBound = declaredParameter.bound;
          DartType interfaceBound = interfaceParameter.bound;
          if (interfaceSubstitution != null) {
            declaredBound = interfaceSubstitution.substituteType(declaredBound);
            interfaceBound =
                interfaceSubstitution.substituteType(interfaceBound);
          }
          DartType computedBound = substitution.substituteType(interfaceBound);
          if (!libraryBuilder.isNonNullableByDefault) {
            computedBound = legacyErasure(computedBound);
          }
          if (declaredNeedsLegacyErasure) {
            declaredBound = legacyErasure(declaredBound);
          }
          if (!types
              .performNullabilityAwareMutualSubtypesCheck(
                  declaredBound, computedBound)
              .isSubtypeWhenUsingNullabilities()) {
            reportInvalidOverride(
                isInterfaceCheck,
                declaredMember,
                templateOverrideTypeVariablesBoundMismatch.withArguments(
                    declaredBound,
                    declaredParameter.name!,
                    "${declaredMember.enclosingClass!.name}."
                        "${declaredMember.name.text}",
                    computedBound,
                    "${interfaceMemberOrigin.enclosingClass!.name}."
                        "${interfaceMemberOrigin.name.text}",
                    libraryBuilder.isNonNullableByDefault),
                declaredMember.fileOffset,
                noLength,
                context: [
                  templateOverriddenMethodCause
                      .withArguments(interfaceMemberOrigin.name.text)
                      .withLocation(_getMemberUri(interfaceMemberOrigin),
                          interfaceMemberOrigin.fileOffset, noLength)
                ]);
          }
        }
      }
      if (interfaceSubstitution != null) {
        interfaceSubstitution =
            Substitution.combine(interfaceSubstitution, substitution);
      } else {
        interfaceSubstitution = substitution;
      }
    }
    return interfaceSubstitution;
  }

  Substitution? _computeDeclaredSubstitution(
      Types types, Member declaredMember) {
    Substitution? declaredSubstitution;
    if (declaredMember.enclosingClass!.typeParameters.isNotEmpty) {
      Class enclosingClass = declaredMember.enclosingClass!;
      declaredSubstitution = Substitution.fromPairs(
          enclosingClass.typeParameters,
          types.hierarchy
              .getTypeArgumentsAsInstanceOf(thisType, enclosingClass)!);
    }
    return declaredSubstitution;
  }

  void _checkTypes(
      Types types,
      Substitution? interfaceSubstitution,
      Substitution? declaredSubstitution,
      Member declaredMember,
      Member interfaceMember,
      Member interfaceMemberOrigin,
      DartType declaredType,
      DartType interfaceType,
      bool isCovariantByDeclaration,
      VariableDeclaration? declaredParameter,
      bool isInterfaceCheck,
      bool declaredNeedsLegacyErasure,
      {bool asIfDeclaredParameter = false}) {
    if (interfaceSubstitution != null) {
      interfaceType = interfaceSubstitution.substituteType(interfaceType);
    }
    if (declaredSubstitution != null) {
      declaredType = declaredSubstitution.substituteType(declaredType);
    }
    if (declaredNeedsLegacyErasure) {
      declaredType = legacyErasure(declaredType);
    }

    if (!declaredMember.isNonNullableByDefault &&
        interfaceMember.isNonNullableByDefault) {
      interfaceType = legacyErasure(interfaceType);
    }

    bool inParameter = declaredParameter != null || asIfDeclaredParameter;
    DartType subtype = inParameter ? interfaceType : declaredType;
    DartType supertype = inParameter ? declaredType : interfaceType;

    if (types.isSubtypeOf(
        subtype, supertype, SubtypeCheckMode.withNullabilities)) {
      // No problem--the proper subtyping relation is satisfied.
    } else if (isCovariantByDeclaration &&
        types.isSubtypeOf(
            supertype, subtype, SubtypeCheckMode.withNullabilities)) {
      // No problem--the overriding parameter is marked "covariant" and has
      // a type which is a subtype of the parameter it overrides.
    } else if (subtype is InvalidType || supertype is InvalidType) {
      // Don't report a problem as something else is wrong that has already
      // been reported.
    } else {
      // Report an error.
      bool isErrorInNnbdOptedOutMode = !types.isSubtypeOf(
              subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
          (!isCovariantByDeclaration ||
              !types.isSubtypeOf(
                  supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
      if (isErrorInNnbdOptedOutMode || libraryBuilder.isNonNullableByDefault) {
        String declaredMemberName = '${declaredMember.enclosingClass!.name}'
            '.${declaredMember.name.text}';
        String interfaceMemberName =
            '${interfaceMemberOrigin.enclosingClass!.name}'
            '.${interfaceMemberOrigin.name.text}';
        Message message;
        int fileOffset;
        if (declaredParameter == null) {
          if (asIfDeclaredParameter) {
            // Setter overridden by field
            message = templateOverrideTypeMismatchSetter.withArguments(
                declaredMemberName,
                declaredType,
                interfaceType,
                interfaceMemberName,
                libraryBuilder.isNonNullableByDefault);
          } else {
            message = templateOverrideTypeMismatchReturnType.withArguments(
                declaredMemberName,
                declaredType,
                interfaceType,
                interfaceMemberName,
                libraryBuilder.isNonNullableByDefault);
          }
          fileOffset = declaredMember.fileOffset;
        } else {
          message = templateOverrideTypeMismatchParameter.withArguments(
              declaredParameter.name!,
              declaredMemberName,
              declaredType,
              interfaceType,
              interfaceMemberName,
              libraryBuilder.isNonNullableByDefault);
          fileOffset = declaredParameter.fileOffset;
        }
        reportInvalidOverride(
            isInterfaceCheck, declaredMember, message, fileOffset, noLength,
            context: [
              templateOverriddenMethodCause
                  .withArguments(interfaceMemberOrigin.name.text)
                  .withLocation(_getMemberUri(interfaceMemberOrigin),
                      interfaceMemberOrigin.fileOffset, noLength)
            ]);
      }
    }
  }

  /// Checks whether [declaredMember] correctly overrides [interfaceMember].
  ///
  /// If an error is reporter [interfaceMemberOrigin] is used as the context
  /// for where [interfaceMember] was declared, since [interfaceMember] might
  /// itself be synthesized.
  ///
  /// Returns whether a covariant parameter was seen and more methods thus have
  /// to be checked.
  bool checkMethodOverride(
      Types types,
      Procedure declaredMember,
      Procedure interfaceMember,
      Member interfaceMemberOrigin,
      bool isInterfaceCheck,
      bool declaredNeedsLegacyErasure) {
    assert(declaredMember.kind == interfaceMember.kind);
    assert(declaredMember.kind == ProcedureKind.Method ||
        declaredMember.kind == ProcedureKind.Operator);
    bool seenCovariant = false;
    FunctionNode declaredFunction = declaredMember.function;
    FunctionType? declaredSignatureType = declaredMember.signatureType;
    FunctionNode interfaceFunction = interfaceMember.function;
    FunctionType? interfaceSignatureType = interfaceMember.signatureType;

    Substitution? interfaceSubstitution = _computeInterfaceSubstitution(
        types,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        declaredFunction,
        interfaceFunction,
        isInterfaceCheck,
        declaredNeedsLegacyErasure);

    Substitution? declaredSubstitution =
        _computeDeclaredSubstitution(types, declaredMember);

    _checkTypes(
        types,
        interfaceSubstitution,
        declaredSubstitution,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        declaredFunction.returnType,
        interfaceFunction.returnType,
        /* isCovariantByDeclaration = */ false,
        /* declaredParameter = */ null,
        isInterfaceCheck,
        declaredNeedsLegacyErasure);
    if (declaredFunction.positionalParameters.length <
        interfaceFunction.positionalParameters.length) {
      reportInvalidOverride(
          isInterfaceCheck,
          declaredMember,
          templateOverrideFewerPositionalArguments.withArguments(
              "${declaredMember.enclosingClass!.name}."
                  "${declaredMember.name.text}",
              "${interfaceMemberOrigin.enclosingClass!.name}."
                  "${interfaceMemberOrigin.name.text}"),
          declaredMember.fileOffset,
          noLength,
          context: [
            templateOverriddenMethodCause
                .withArguments(interfaceMemberOrigin.name.text)
                .withLocation(interfaceMemberOrigin.fileUri,
                    interfaceMemberOrigin.fileOffset, noLength)
          ]);
    }
    if (interfaceFunction.requiredParameterCount <
        declaredFunction.requiredParameterCount) {
      reportInvalidOverride(
          isInterfaceCheck,
          declaredMember,
          templateOverrideMoreRequiredArguments.withArguments(
              "${declaredMember.enclosingClass!.name}."
                  "${declaredMember.name.text}",
              "${interfaceMemberOrigin.enclosingClass!.name}."
                  "${interfaceMemberOrigin.name.text}"),
          declaredMember.fileOffset,
          noLength,
          context: [
            templateOverriddenMethodCause
                .withArguments(interfaceMemberOrigin.name.text)
                .withLocation(interfaceMemberOrigin.fileUri,
                    interfaceMemberOrigin.fileOffset, noLength)
          ]);
    }
    for (int i = 0;
        i < declaredFunction.positionalParameters.length &&
            i < interfaceFunction.positionalParameters.length;
        i++) {
      VariableDeclaration declaredParameter =
          declaredFunction.positionalParameters[i];
      VariableDeclaration interfaceParameter =
          interfaceFunction.positionalParameters[i];
      DartType declaredParameterType = declaredParameter.type;
      if (declaredSignatureType != null) {
        declaredParameterType = declaredSignatureType.positionalParameters[i];
      }
      DartType interfaceParameterType = interfaceParameter.type;
      if (interfaceSignatureType != null) {
        interfaceParameterType = interfaceSignatureType.positionalParameters[i];
      }
      if (i == 0 &&
          declaredMember.name == equalsName &&
          declaredParameterType ==
              types.hierarchy.coreTypes.objectNonNullableRawType &&
          interfaceParameter.type is DynamicType) {
        // TODO(johnniwinther): Add check for opt-in overrides of operator ==.
        // `operator ==` methods in opt-out classes have type
        // `bool Function(dynamic)`.
        continue;
      }

      _checkTypes(
          types,
          interfaceSubstitution,
          declaredSubstitution,
          declaredMember,
          interfaceMember,
          interfaceMemberOrigin,
          declaredParameterType,
          interfaceParameterType,
          declaredParameter.isCovariantByDeclaration ||
              interfaceParameter.isCovariantByDeclaration,
          declaredParameter,
          isInterfaceCheck,
          declaredNeedsLegacyErasure);
      if (declaredParameter.isCovariantByDeclaration) seenCovariant = true;
    }
    if (declaredFunction.namedParameters.isEmpty &&
        interfaceFunction.namedParameters.isEmpty) {
      return seenCovariant;
    }
    if (declaredFunction.namedParameters.length <
        interfaceFunction.namedParameters.length) {
      reportInvalidOverride(
          isInterfaceCheck,
          declaredMember,
          templateOverrideFewerNamedArguments.withArguments(
              "${declaredMember.enclosingClass!.name}."
                  "${declaredMember.name.text}",
              "${interfaceMemberOrigin.enclosingClass!.name}."
                  "${interfaceMemberOrigin.name.text}"),
          declaredMember.fileOffset,
          noLength,
          context: [
            templateOverriddenMethodCause
                .withArguments(interfaceMemberOrigin.name.text)
                .withLocation(interfaceMemberOrigin.fileUri,
                    interfaceMemberOrigin.fileOffset, noLength)
          ]);
    }

    int compareNamedParameters(VariableDeclaration p0, VariableDeclaration p1) {
      return p0.name!.compareTo(p1.name!);
    }

    List<VariableDeclaration> sortedFromDeclared =
        new List.of(declaredFunction.namedParameters)
          ..sort(compareNamedParameters);
    List<VariableDeclaration> sortedFromInterface =
        new List.of(interfaceFunction.namedParameters)
          ..sort(compareNamedParameters);
    Iterator<VariableDeclaration> declaredNamedParameters =
        sortedFromDeclared.iterator;
    Iterator<VariableDeclaration> interfaceNamedParameters =
        sortedFromInterface.iterator;
    outer:
    while (declaredNamedParameters.moveNext() &&
        interfaceNamedParameters.moveNext()) {
      while (declaredNamedParameters.current.name !=
          interfaceNamedParameters.current.name) {
        if (!declaredNamedParameters.moveNext()) {
          reportInvalidOverride(
              isInterfaceCheck,
              declaredMember,
              templateOverrideMismatchNamedParameter.withArguments(
                  "${declaredMember.enclosingClass!.name}."
                      "${declaredMember.name.text}",
                  interfaceNamedParameters.current.name!,
                  "${interfaceMember.enclosingClass!.name}."
                      "${interfaceMember.name.text}"),
              declaredMember.fileOffset,
              noLength,
              context: [
                templateOverriddenMethodCause
                    .withArguments(interfaceMember.name.text)
                    .withLocation(interfaceMember.fileUri,
                        interfaceMember.fileOffset, noLength)
              ]);
          break outer;
        }
      }
      VariableDeclaration declaredParameter = declaredNamedParameters.current;
      _checkTypes(
          types,
          interfaceSubstitution,
          declaredSubstitution,
          declaredMember,
          interfaceMember,
          interfaceMemberOrigin,
          declaredParameter.type,
          interfaceNamedParameters.current.type,
          declaredParameter.isCovariantByDeclaration,
          declaredParameter,
          isInterfaceCheck,
          declaredNeedsLegacyErasure);
      if (declaredMember.isNonNullableByDefault &&
          !declaredNeedsLegacyErasure &&
          declaredParameter.isRequired &&
          interfaceMember.isNonNullableByDefault &&
          !interfaceNamedParameters.current.isRequired) {
        reportInvalidOverride(
            isInterfaceCheck,
            declaredMember,
            templateOverrideMismatchRequiredNamedParameter.withArguments(
                declaredParameter.name!,
                "${declaredMember.enclosingClass!.name}."
                    "${declaredMember.name.text}",
                "${interfaceMember.enclosingClass!.name}."
                    "${interfaceMember.name.text}"),
            declaredParameter.fileOffset,
            noLength,
            context: [
              templateOverriddenMethodCause
                  .withArguments(interfaceMemberOrigin.name.text)
                  .withLocation(_getMemberUri(interfaceMemberOrigin),
                      interfaceMemberOrigin.fileOffset, noLength)
            ]);
      }
      if (declaredParameter.isCovariantByDeclaration) seenCovariant = true;
    }
    return seenCovariant;
  }

  /// Checks whether [declaredMember] correctly overrides [interfaceMember].
  ///
  /// If an error is reporter [interfaceMemberOrigin] is used as the context
  /// for where [interfaceMember] was declared, since [interfaceMember] might
  /// itself be synthesized.
  void checkGetterOverride(
      Types types,
      Member declaredMember,
      Member interfaceMember,
      Member interfaceMemberOrigin,
      bool isInterfaceCheck,
      bool declaredNeedsLegacyErasure) {
    Substitution? interfaceSubstitution = _computeInterfaceSubstitution(
        types,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        /* declaredFunction = */ null,
        /* interfaceFunction = */ null,
        isInterfaceCheck,
        declaredNeedsLegacyErasure);
    Substitution? declaredSubstitution =
        _computeDeclaredSubstitution(types, declaredMember);
    DartType declaredType = declaredMember.getterType;
    DartType interfaceType = interfaceMember.getterType;
    _checkTypes(
        types,
        interfaceSubstitution,
        declaredSubstitution,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        declaredType,
        interfaceType,
        /* isCovariantByDeclaration = */ false,
        /* declaredParameter = */ null,
        isInterfaceCheck,
        declaredNeedsLegacyErasure);
  }

  /// Checks whether [declaredMember] correctly overrides [interfaceMember].
  ///
  /// If an error is reporter [interfaceMemberOrigin] is used as the context
  /// for where [interfaceMember] was declared, since [interfaceMember] might
  /// itself be synthesized.
  ///
  /// Returns whether a covariant parameter was seen and more methods thus have
  /// to be checked.
  bool checkSetterOverride(
      Types types,
      Member declaredMember,
      Member interfaceMember,
      Member interfaceMemberOrigin,
      bool isInterfaceCheck,
      bool declaredNeedsLegacyErasure) {
    Substitution? interfaceSubstitution = _computeInterfaceSubstitution(
        types,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        /* declaredFunction = */ null,
        /* interfaceFunction = */ null,
        isInterfaceCheck,
        declaredNeedsLegacyErasure);
    Substitution? declaredSubstitution =
        _computeDeclaredSubstitution(types, declaredMember);
    DartType declaredType = declaredMember.setterType;
    DartType interfaceType = interfaceMember.setterType;
    VariableDeclaration? declaredParameter =
        declaredMember.function?.positionalParameters.elementAt(0);
    bool isCovariantByDeclaration =
        declaredParameter?.isCovariantByDeclaration ?? false;
    if (!isCovariantByDeclaration && declaredMember is Field) {
      isCovariantByDeclaration = declaredMember.isCovariantByDeclaration;
    }
    if (!isCovariantByDeclaration && interfaceMember is Field) {
      isCovariantByDeclaration = interfaceMember.isCovariantByDeclaration;
    }
    _checkTypes(
        types,
        interfaceSubstitution,
        declaredSubstitution,
        declaredMember,
        interfaceMember,
        interfaceMemberOrigin,
        declaredType,
        interfaceType,
        isCovariantByDeclaration,
        declaredParameter,
        isInterfaceCheck,
        declaredNeedsLegacyErasure,
        asIfDeclaredParameter: true);
    return isCovariantByDeclaration;
  }

  // When the overriding member is inherited, report the class containing
  // the conflict as the main error.
  void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
      Message message, int fileOffset, int length,
      {List<LocatedMessage>? context}) {
    if (shouldOverrideProblemBeOverlooked(this)) {
      return;
    }

    if (declaredMember.enclosingClass == cls) {
      // Ordinary override
      libraryBuilder.addProblem(
          message, fileOffset, length, declaredMember.fileUri,
          context: context);
    } else {
      context = [
        message.withLocation(declaredMember.fileUri, fileOffset, length),
        ...?context
      ];
      if (isInterfaceCheck) {
        // Interface check
        libraryBuilder.addProblem(
            templateInterfaceCheck.withArguments(
                declaredMember.name.text, cls.name),
            cls.fileOffset,
            cls.name.length,
            cls.fileUri,
            context: context);
      } else {
        if (cls.isAnonymousMixin) {
          // Implicit mixin application class
          String baseName = cls.superclass!.demangledName;
          String mixinName = cls.mixedInClass!.name;
          int classNameLength = cls.nameAsMixinApplicationSubclass.length;
          libraryBuilder.addProblem(
              templateImplicitMixinOverride.withArguments(
                  mixinName, baseName, declaredMember.name.text),
              cls.fileOffset,
              classNameLength,
              cls.fileUri,
              context: context);
        } else {
          // Named mixin application class
          libraryBuilder.addProblem(
              templateNamedMixinOverride.withArguments(
                  cls.name, declaredMember.name.text),
              cls.fileOffset,
              cls.name.length,
              cls.fileUri,
              context: context);
        }
      }
    }
  }
}

/// Returns `true` if override problems should be overlooked.
///
/// This is needed for the current encoding of some JavaScript implementation
/// classes that are not valid Dart. For instance `JSInt` in
/// 'dart:_interceptors' that implements both `int` and `double`, and `JsArray`
/// in `dart:js` that implement both `ListMixin` and `JsObject`.
bool shouldOverrideProblemBeOverlooked(ClassBuilder classBuilder) {
  return getOverlookedOverrideProblemChoice(classBuilder) != null;
}

/// Returns the index of the member to use if an override problems should be
/// overlooked.
///
/// This is needed for the current encoding of some JavaScript implementation
/// classes that are not valid Dart. For instance `JSInt` in
/// 'dart:_interceptors' that implements both `int` and `double`, and `JsArray`
/// in `dart:js` that implement both `ListMixin` and `JsObject`.
int? getOverlookedOverrideProblemChoice(ClassBuilder classBuilder) {
  String uri = '${classBuilder.libraryBuilder.importUri}';
  if (uri == 'dart:js' && classBuilder.fileUri.pathSegments.last == 'js.dart') {
    return 0;
  } else if (uri == 'dart:_interceptors' &&
      classBuilder.fileUri.pathSegments.last == 'js_number.dart') {
    return 1;
  }
  return null;
}

class _RedirectingConstructorsFieldBuilder extends DillFieldBuilder
    with SourceMemberBuilderMixin {
  _RedirectingConstructorsFieldBuilder(Field field, SourceClassBuilder parent)
      : super(field, parent);

  @override
  SourceLibraryBuilder get libraryBuilder =>
      super.libraryBuilder as SourceLibraryBuilder;

  @override
  void buildOutlineExpressions(
      ClassHierarchy classHierarchy,
      List<DelayedActionPerformer> delayedActionPerformers,
      List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
    // Do nothing.
  }

  @override
  void checkVariance(
      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}

  @override
  void checkTypes(
      SourceLibraryBuilder library, TypeEnvironment typeEnvironment) {}
}

class ClassMemberNameIterator<T extends Builder> implements NameIterator<T> {
  NameIterator<T>? _iterator;
  Iterator<SourceClassBuilder>? augmentationBuilders;
  final bool includeDuplicates;

  factory ClassMemberNameIterator(SourceClassBuilder classBuilder,
      {required bool includeDuplicates}) {
    return new ClassMemberNameIterator._(classBuilder.origin,
        includeDuplicates: includeDuplicates);
  }

  ClassMemberNameIterator._(SourceClassBuilder classBuilder,
      {required this.includeDuplicates})
      : _iterator = classBuilder.scope.filteredNameIterator<T>(
            parent: classBuilder,
            includeDuplicates: includeDuplicates,
            includeAugmentations: false),
        augmentationBuilders = classBuilder._patches?.iterator;

  @override
  bool moveNext() {
    if (_iterator != null) {
      if (_iterator!.moveNext()) {
        return true;
      }
    }
    if (augmentationBuilders != null && augmentationBuilders!.moveNext()) {
      SourceClassBuilder augmentationClassBuilder =
          augmentationBuilders!.current;
      _iterator = augmentationClassBuilder.scope.filteredNameIterator<T>(
          parent: augmentationClassBuilder,
          includeDuplicates: includeDuplicates,
          includeAugmentations: false);
    }
    if (_iterator != null) {
      if (_iterator!.moveNext()) {
        return true;
      }
    }
    return false;
  }

  @override
  T get current => _iterator?.current ?? (throw new StateError('No element'));

  @override
  String get name => _iterator?.name ?? (throw new StateError('No element'));
}

class ClassConstructorNameIterator<T extends MemberBuilder>
    implements NameIterator<T> {
  NameIterator<T>? _iterator;
  Iterator<SourceClassBuilder>? augmentationBuilders;
  final bool includeDuplicates;

  factory ClassConstructorNameIterator(SourceClassBuilder classBuilder,
      {required bool includeDuplicates}) {
    return new ClassConstructorNameIterator._(classBuilder.origin,
        includeDuplicates: includeDuplicates);
  }

  ClassConstructorNameIterator._(SourceClassBuilder classBuilder,
      {required this.includeDuplicates})
      : _iterator = classBuilder.constructorScope.filteredNameIterator<T>(
            parent: classBuilder,
            includeDuplicates: includeDuplicates,
            includeAugmentations: false),
        augmentationBuilders = classBuilder._patches?.iterator;

  @override
  bool moveNext() {
    if (_iterator != null) {
      if (_iterator!.moveNext()) {
        return true;
      }
    }
    if (augmentationBuilders != null && augmentationBuilders!.moveNext()) {
      SourceClassBuilder augmentationClassBuilder =
          augmentationBuilders!.current;
      _iterator = augmentationClassBuilder.constructorScope
          .filteredNameIterator<T>(
              parent: augmentationClassBuilder,
              includeDuplicates: includeDuplicates,
              includeAugmentations: false);
    }
    if (_iterator != null) {
      if (_iterator!.moveNext()) {
        return true;
      }
    }
    return false;
  }

  @override
  T get current => _iterator?.current ?? (throw new StateError('No element'));

  @override
  String get name => _iterator?.name ?? (throw new StateError('No element'));
}
