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

import 'package:js_shared/variance.dart';

import '../common.dart';
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart';
import '../ir/element_map.dart';
import '../js_backend/native_data.dart' show NativeBasicData;
import '../js_model/locals.dart';
import '../universe/selector.dart' show Selector;
import '../universe/world_builder.dart';

import 'names.dart' show Identifiers, Uris;

/// The common elements and types in Dart.
abstract class CommonElements {
  final DartTypes dartTypes;
  final ElementEnvironment _env;
  ClassEntity? _symbolClass;
  ConstructorEntity? _symbolConstructorTarget;
  bool _computedSymbolConstructorDependencies = false;
  ConstructorEntity? _symbolConstructorImplementationTarget;
  ClassEntity? _mapLiteralClass;
  ClassEntity? _symbolImplementationClass;
  FieldEntity? _symbolImplementationField;

  CommonElements(this.dartTypes, this._env);

  /// The `Object` class defined in 'dart:core'.
  late final ClassEntity objectClass = _findClass(coreLibrary, 'Object');

  /// The `bool` class defined in 'dart:core'.
  late final ClassEntity boolClass = _findClass(coreLibrary, 'bool');

  /// The `num` class defined in 'dart:core'.
  late final ClassEntity numClass = _findClass(coreLibrary, 'num');

  /// The `int` class defined in 'dart:core'.
  late final ClassEntity intClass = _findClass(coreLibrary, 'int');

  /// The `double` class defined in 'dart:core'.
  late final ClassEntity doubleClass = _findClass(coreLibrary, 'double');

  /// The `String` class defined in 'dart:core'.
  late final ClassEntity stringClass = _findClass(coreLibrary, 'String');

  /// The `Function` class defined in 'dart:core'.
  late final ClassEntity functionClass = _findClass(coreLibrary, 'Function');

  /// The `Record` class defined in 'dart:core'.
  late final ClassEntity recordClass = _findClass(coreLibrary, 'Record');

  /// The `Resource` class defined in 'dart:core'.
  late final ClassEntity resourceClass = _findClass(coreLibrary, 'Resource');

  /// The `Symbol` class defined in 'dart:core'.
  late final ClassEntity symbolClass = _findClass(coreLibrary, 'Symbol');

  /// The `Null` class defined in 'dart:core'.
  late final ClassEntity nullClass = _findClass(coreLibrary, 'Null');

  /// The `Type` class defined in 'dart:core'.
  late final ClassEntity typeClass = _findClass(coreLibrary, 'Type');

  /// The `StackTrace` class defined in 'dart:core';
  late final ClassEntity stackTraceClass =
      _findClass(coreLibrary, 'StackTrace');

  /// The `List` class defined in 'dart:core';
  late final ClassEntity listClass = _findClass(coreLibrary, 'List');

  /// The `Set` class defined in 'dart:core';
  late final ClassEntity setClass = _findClass(coreLibrary, 'Set');

  /// The `Map` class defined in 'dart:core';
  late final ClassEntity mapClass = _findClass(coreLibrary, 'Map');

  /// The `Set` class defined in 'dart:core';
  late final ClassEntity unmodifiableSetClass =
      _findClass(collectionLibrary, '_UnmodifiableSet');

  /// The `Iterable` class defined in 'dart:core';
  late final ClassEntity iterableClass = _findClass(coreLibrary, 'Iterable');

  /// The `Future` class defined in 'async';.
  late final ClassEntity futureClass = _findClass(asyncLibrary, 'Future');

  /// The `Stream` class defined in 'async';
  late final ClassEntity streamClass = _findClass(asyncLibrary, 'Stream');

  /// The dart:core library.
  late final LibraryEntity coreLibrary =
      _env.lookupLibrary(Uris.dart_core, required: true)!;

  /// The dart:async library.
  late final LibraryEntity? asyncLibrary = _env.lookupLibrary(Uris.dart_async);

  /// The dart:collection library.
  late final LibraryEntity? collectionLibrary =
      _env.lookupLibrary(Uris.dart_collection);

  /// The dart:mirrors library.
  /// Null if the program doesn't access dart:mirrors.
  late final LibraryEntity? mirrorsLibrary =
      _env.lookupLibrary(Uris.dart_mirrors);

  /// The dart:typed_data library.
  late final LibraryEntity typedDataLibrary =
      _env.lookupLibrary(Uris.dart__native_typed_data, required: true)!;

  /// The dart:_js_shared_embedded_names library.
  late final LibraryEntity sharedEmbeddedNamesLibrary =
      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true)!;

  /// The dart:_js_helper library.
  late final LibraryEntity? jsHelperLibrary =
      _env.lookupLibrary(Uris.dart__js_helper);

  /// The dart:_late_helper library
  late final LibraryEntity? lateHelperLibrary =
      _env.lookupLibrary(Uris.dart__late_helper);

  /// The dart:_interceptors library.
  late final LibraryEntity? interceptorsLibrary =
      _env.lookupLibrary(Uris.dart__interceptors);

  /// The dart:_foreign_helper library.
  late final LibraryEntity? foreignLibrary =
      _env.lookupLibrary(Uris.dart__foreign_helper);

  /// The dart:_rti library.
  late final LibraryEntity rtiLibrary =
      _env.lookupLibrary(Uris.dart__rti, required: true)!;

  /// The dart:_internal library.
  late final LibraryEntity internalLibrary =
      _env.lookupLibrary(Uris.dart__internal, required: true)!;

  /// The dart:js_util library.
  late final LibraryEntity? dartJsUtilLibrary =
      _env.lookupLibrary(Uris.dart_js_util);

  /// The package:js library.
  late final LibraryEntity? packageJsLibrary =
      _env.lookupLibrary(Uris.package_js);

  /// The dart:_js_annotations library.
  late final LibraryEntity? dartJsAnnotationsLibrary =
      _env.lookupLibrary(Uris.dart__js_annotations);

  /// The dart:js_interop library.
  late final LibraryEntity? dartJsInteropLibrary =
      _env.lookupLibrary(Uris.dart__js_interop);

  /// The `NativeTypedData` class from dart:typed_data.
  ClassEntity get typedDataClass =>
      _findClass(typedDataLibrary, 'NativeTypedData');

  /// Constructor of the `Symbol` class in dart:internal.
  ///
  /// This getter will ensure that `Symbol` is resolved and lookup the
  /// constructor on demand.
  ConstructorEntity get symbolConstructorTarget {
    // TODO(johnniwinther): Kernel does not include redirecting factories
    // so this cannot be found in kernel. Find a consistent way to handle
    // this and similar cases.
    return _symbolConstructorTarget ??=
        _env.lookupConstructor(symbolImplementationClass, '')!;
  }

  void _ensureSymbolConstructorDependencies() {
    if (_computedSymbolConstructorDependencies) return;
    _computedSymbolConstructorDependencies = true;
    if (_symbolConstructorTarget == null) {
      if (_symbolImplementationClass == null) {
        _symbolImplementationClass =
            _findClassOrNull(internalLibrary, 'Symbol');
      }
      if (_symbolImplementationClass != null) {
        _symbolConstructorTarget = _env.lookupConstructor(
            _symbolImplementationClass!, '',
            required: false);
      }
    }
    if (_symbolClass == null) {
      _symbolClass = _findClassOrNull(coreLibrary, 'Symbol');
    }
    if (_symbolClass == null) {
      return;
    }
    _symbolConstructorImplementationTarget =
        _env.lookupConstructor(symbolClass, '', required: false);
  }

  /// Whether [element] is the same as [symbolConstructor].
  ///
  /// Used to check for the constructor without computing it until it is likely
  /// to be seen.
  bool isSymbolConstructor(ConstructorEntity element) {
    _ensureSymbolConstructorDependencies();
    return element == _symbolConstructorImplementationTarget ||
        element == _symbolConstructorTarget;
  }

  /// The function `identical` in dart:core.
  late final FunctionEntity identicalFunction =
      _findLibraryMember(coreLibrary, 'identical')!;

  /// Whether [element] is the `Function.apply` method.
  ///
  /// This will not resolve the apply method if it hasn't been seen yet during
  /// compilation.
  bool isFunctionApplyMethod(MemberEntity element) =>
      element.name == 'apply' && element.enclosingClass == functionClass;

  /// The `dynamic` type.
  DynamicType get dynamicType => _env.dynamicType as DynamicType;

  /// The `Object` type defined in 'dart:core'.
  InterfaceType get objectType => _getRawType(objectClass);

  /// The `bool` type defined in 'dart:core'.
  InterfaceType get boolType => _getRawType(boolClass);

  /// The `num` type defined in 'dart:core'.
  InterfaceType get numType => _getRawType(numClass);

  /// The `int` type defined in 'dart:core'.
  InterfaceType get intType => _getRawType(intClass);

  /// The `double` type defined in 'dart:core'.
  InterfaceType get doubleType => _getRawType(doubleClass);

  /// The `String` type defined in 'dart:core'.
  InterfaceType get stringType => _getRawType(stringClass);

  /// The `Symbol` type defined in 'dart:core'.
  InterfaceType get symbolType => _getRawType(symbolClass);

  /// The `Function` type defined in 'dart:core'.
  InterfaceType get functionType => _getRawType(functionClass);

  /// The `Null` type defined in 'dart:core'.
  InterfaceType get nullType => _getRawType(nullClass);

  /// The `Record` type defined in 'dart:core'.
  InterfaceType get recordType => _getRawType(recordClass);

  /// The `Type` type defined in 'dart:core'.
  InterfaceType get typeType => _getRawType(typeClass);

  InterfaceType get typeLiteralType => _getRawType(typeLiteralClass);

  /// The `StackTrace` type defined in 'dart:core';
  InterfaceType get stackTraceType => _getRawType(stackTraceClass);

  /// Returns an instance of the `List` type defined in 'dart:core' with
  /// [elementType] as its type argument.
  ///
  /// If no type argument is provided, the canonical raw type is returned.
  InterfaceType listType([DartType? elementType]) {
    if (elementType == null) {
      return _getRawType(listClass);
    }
    return _createInterfaceType(listClass, [elementType]);
  }

  /// Returns an instance of the `Set` type defined in 'dart:core' with
  /// [elementType] as its type argument.
  ///
  /// If no type argument is provided, the canonical raw type is returned.
  InterfaceType setType([DartType? elementType]) {
    if (elementType == null) {
      return _getRawType(setClass);
    }
    return _createInterfaceType(setClass, [elementType]);
  }

  /// Returns an instance of the `Map` type defined in 'dart:core' with
  /// [keyType] and [valueType] as its type arguments.
  ///
  /// If no type arguments are provided, the canonical raw type is returned.

  InterfaceType mapType([DartType? keyType, DartType? valueType]) {
    if (keyType == null && valueType == null) {
      return _getRawType(mapClass);
    } else if (keyType == null) {
      keyType = dynamicType;
    } else if (valueType == null) {
      valueType = dynamicType;
    }
    return _createInterfaceType(mapClass, [keyType, valueType!]);
  }

  /// Returns an instance of the `Iterable` type defined in 'dart:core' with
  /// [elementType] as its type argument.
  ///
  /// If no type argument is provided, the canonical raw type is returned.
  InterfaceType iterableType([DartType? elementType]) {
    if (elementType == null) {
      return _getRawType(iterableClass);
    }
    return _createInterfaceType(iterableClass, [elementType]);
  }

  /// Returns an instance of the `Future` type defined in 'dart:async' with
  /// [elementType] as its type argument.
  ///
  /// If no type argument is provided, the canonical raw type is returned.
  // CommonElementsForDartTypes
  InterfaceType futureType([DartType? elementType]) {
    if (elementType == null) {
      return _getRawType(futureClass);
    }
    return _createInterfaceType(futureClass, [elementType]);
  }

  /// Returns an instance of the `Stream` type defined in 'dart:async' with
  /// [elementType] as its type argument.
  ///
  /// If no type argument is provided, the canonical raw type is returned.
  InterfaceType streamType([DartType? elementType]) {
    if (elementType == null) {
      return _getRawType(streamClass);
    }
    return _createInterfaceType(streamClass, [elementType]);
  }

  ClassEntity _findClass(LibraryEntity? library, String name) {
    return _env.lookupClass(library!, name, required: true)!;
  }

  ClassEntity? _findClassOrNull(LibraryEntity? library, String name) {
    if (library == null) return null;
    return _env.lookupClass(library, name, required: false);
  }

  T? _findLibraryMember<T extends MemberEntity>(
      LibraryEntity? library, String name,
      {bool setter = false, bool required = true}) {
    if (library == null) return null;
    return _env.lookupLibraryMember(library, name,
        setter: setter, required: required) as T?;
  }

  T? _findClassMemberOrNull<T extends MemberEntity>(
      ClassEntity cls, String name) {
    return _env.lookupLocalClassMember(
        cls, Name(name, cls.library.canonicalUri, isSetter: false),
        required: false) as T?;
  }

  T _findClassMember<T extends MemberEntity>(ClassEntity cls, String name) {
    return _env.lookupLocalClassMember(
        cls, Name(name, cls.library.canonicalUri, isSetter: false),
        required: true) as T;
  }

  /// Return the raw type of [cls].
  InterfaceType _getRawType(ClassEntity cls) {
    return _env.getRawType(cls);
  }

  /// Create the instantiation of [cls] with the given [typeArguments] and
  /// [nullability].
  InterfaceType _createInterfaceType(
      ClassEntity cls, List<DartType> typeArguments) {
    return _env.createInterfaceType(cls, typeArguments);
  }

  InterfaceType getConstantListTypeFor(InterfaceType sourceType) {
    // TODO(51534): Use CONST_CANONICAL_TYPE(T_i) for arguments.
    return _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
  }

  InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
      {bool onlyStringKeys = false}) {
    // TODO(51534): Use CONST_CANONICAL_TYPE(T_i) for arguments.
    ClassEntity classElement =
        onlyStringKeys ? constantStringMapClass : generalConstantMapClass;
    return _env.createInterfaceType(classElement, sourceType.typeArguments);
  }

  InterfaceType getConstantSetTypeFor(InterfaceType sourceType,
      {bool onlyStringKeys = false}) {
    // TODO(51534): Use CONST_CANONICAL_TYPE(T_i) for arguments.
    ClassEntity classElement =
        onlyStringKeys ? constantStringSetClass : generalConstantSetClass;
    return _env.createInterfaceType(classElement, sourceType.typeArguments);
  }

  /// Returns the field that holds the internal name in the implementation class
  /// for `Symbol`.

  FieldEntity get symbolField =>
      _symbolImplementationField ??= _env.lookupLocalClassMember(
          symbolImplementationClass,
          PrivateName('_name', symbolImplementationClass.library.canonicalUri),
          required: true) as FieldEntity;

  InterfaceType get symbolImplementationType =>
      _env.getRawType(symbolImplementationClass);

  // From dart:core
  ClassEntity get mapLiteralClass {
    if (_mapLiteralClass == null) {
      _mapLiteralClass = _env.lookupClass(coreLibrary, 'LinkedHashMap');
      if (_mapLiteralClass == null) {
        _mapLiteralClass = _findClass(collectionLibrary, 'LinkedHashMap');
      }
    }
    return _mapLiteralClass!;
  }

  late final ConstructorEntity mapLiteralConstructor =
      _env.lookupConstructor(mapLiteralClass, '_literal')!;
  late final ConstructorEntity mapLiteralConstructorEmpty =
      _env.lookupConstructor(mapLiteralClass, '_empty')!;
  late final FunctionEntity mapLiteralUntypedMaker =
      _env.lookupLocalClassMember(mapLiteralClass,
              PrivateName('_makeLiteral', mapLiteralClass.library.canonicalUri))
          as FunctionEntity;
  late final FunctionEntity mapLiteralUntypedEmptyMaker =
      _env.lookupLocalClassMember(mapLiteralClass,
              PrivateName('_makeEmpty', mapLiteralClass.library.canonicalUri))
          as FunctionEntity;

  late final ClassEntity setLiteralClass =
      _findClass(collectionLibrary, 'LinkedHashSet');

  late final ConstructorEntity setLiteralConstructor =
      _env.lookupConstructor(setLiteralClass, '_literal')!;
  late final ConstructorEntity setLiteralConstructorEmpty =
      _env.lookupConstructor(setLiteralClass, '_empty')!;
  late final FunctionEntity setLiteralUntypedMaker =
      _env.lookupLocalClassMember(setLiteralClass,
              PrivateName('_makeLiteral', setLiteralClass.library.canonicalUri))
          as FunctionEntity;
  late final FunctionEntity setLiteralUntypedEmptyMaker =
      _env.lookupLocalClassMember(setLiteralClass,
              PrivateName('_makeEmpty', setLiteralClass.library.canonicalUri))
          as FunctionEntity;

  late final FunctionEntity? objectNoSuchMethod = _env.lookupLocalClassMember(
          objectClass, const PublicName(Identifiers.noSuchMethod_))
      as FunctionEntity?;

  bool isDefaultNoSuchMethodImplementation(FunctionEntity element) {
    ClassEntity? classElement = element.enclosingClass;
    return classElement == objectClass ||
        classElement == jsInterceptorClass ||
        classElement == jsNullClass;
  }

  // From dart:async
  ClassEntity _findAsyncHelperClass(String name) =>
      _findClass(asyncLibrary, name);

  FunctionEntity _findAsyncHelperFunction(String name) =>
      _findLibraryMember(asyncLibrary, name)!;

  FunctionEntity get asyncHelperStartSync =>
      _findAsyncHelperFunction("_asyncStartSync");

  FunctionEntity get asyncHelperAwait =>
      _findAsyncHelperFunction("_asyncAwait");

  FunctionEntity get asyncHelperReturn =>
      _findAsyncHelperFunction("_asyncReturn");

  FunctionEntity get asyncHelperRethrow =>
      _findAsyncHelperFunction("_asyncRethrow");

  FunctionEntity get wrapBody =>
      _findAsyncHelperFunction("_wrapJsFunctionForAsync");

  FunctionEntity get yieldStar => _env.lookupLocalClassMember(
      _findAsyncHelperClass("_IterationMarker"),
      const PublicName("yieldStar")) as FunctionEntity;

  FunctionEntity get yieldSingle => _env.lookupLocalClassMember(
      _findAsyncHelperClass("_IterationMarker"),
      const PublicName("yieldSingle")) as FunctionEntity;

  FunctionEntity get syncStarUncaughtError => _env.lookupLocalClassMember(
      _findAsyncHelperClass("_IterationMarker"),
      const PublicName("uncaughtError")) as FunctionEntity;

  FunctionEntity get asyncStarHelper =>
      _findAsyncHelperFunction("_asyncStarHelper");

  FunctionEntity get streamOfController =>
      _findAsyncHelperFunction("_streamOfController");

  FunctionEntity get endOfIteration => _env.lookupLocalClassMember(
      _findAsyncHelperClass("_IterationMarker"),
      const PublicName("endOfIteration")) as FunctionEntity;

  ClassEntity get syncStarIterable =>
      _findAsyncHelperClass("_SyncStarIterable");

  late final ClassEntity _syncStarIteratorClass =
      _findAsyncHelperClass('_SyncStarIterator');

  late final FieldEntity syncStarIteratorCurrentField =
      _findClassMember(_syncStarIteratorClass, '_current');

  late final FieldEntity syncStarIteratorDatumField =
      _findClassMember(_syncStarIteratorClass, '_datum');

  late final FunctionEntity syncStarIteratorYieldStarMethod =
      _findClassMember(_syncStarIteratorClass, '_yieldStar');

  ClassEntity get futureImplementation => _findAsyncHelperClass('_Future');

  ClassEntity get controllerStream =>
      _findAsyncHelperClass("_ControllerStream");

  ClassEntity get streamIterator => _findAsyncHelperClass("StreamIterator");

  ConstructorEntity get streamIteratorConstructor =>
      _env.lookupConstructor(streamIterator, "")!;

  late final FunctionEntity syncStarIterableFactory =
      _findAsyncHelperFunction('_makeSyncStarIterable');

  late final FunctionEntity asyncAwaitCompleterFactory =
      _findAsyncHelperFunction('_makeAsyncAwaitCompleter');

  late final FunctionEntity asyncStarStreamControllerFactory =
      _findAsyncHelperFunction('_makeAsyncStarStreamController');

  // From dart:_interceptors
  ClassEntity _findInterceptorsClass(String name) =>
      _findClass(interceptorsLibrary, name);

  FunctionEntity _findInterceptorsFunction(String name) =>
      _findLibraryMember(interceptorsLibrary, name)!;

  late final ClassEntity jsInterceptorClass =
      _findInterceptorsClass('Interceptor');

  late final ClassEntity jsStringClass = _findInterceptorsClass('JSString');

  late final ClassEntity jsArrayClass = _findInterceptorsClass('JSArray');

  late final ClassEntity jsNumberClass = _findInterceptorsClass('JSNumber');

  late final ClassEntity jsIntClass = _findInterceptorsClass('JSInt');

  late final ClassEntity jsNumNotIntClass =
      _findInterceptorsClass('JSNumNotInt');

  late final ClassEntity jsNullClass = _findInterceptorsClass('JSNull');

  late final ClassEntity jsBoolClass = _findInterceptorsClass('JSBool');

  late final ClassEntity jsPlainJavaScriptObjectClass =
      _findInterceptorsClass('PlainJavaScriptObject');

  late final ClassEntity jsUnknownJavaScriptObjectClass =
      _findInterceptorsClass('UnknownJavaScriptObject');

  late final ClassEntity jsJavaScriptBigIntClass =
      _findInterceptorsClass('JavaScriptBigInt');

  late final ClassEntity jsJavaScriptFunctionClass =
      _findInterceptorsClass('JavaScriptFunction');

  late final ClassEntity jsJavaScriptSymbolClass =
      _findInterceptorsClass('JavaScriptSymbol');

  InterfaceType get jsJavaScriptFunctionType =>
      _getRawType(jsJavaScriptFunctionClass);

  late final ClassEntity jsLegacyJavaScriptObjectClass =
      _findInterceptorsClass('LegacyJavaScriptObject');

  late final ClassEntity jsJavaScriptObjectClass =
      _findInterceptorsClass('JavaScriptObject');

  InterfaceType get jsJavaScriptObjectType =>
      _getRawType(jsJavaScriptObjectClass);

  late final ClassEntity jsIndexableClass =
      _findInterceptorsClass('JSIndexable');

  late final ClassEntity jsMutableIndexableClass =
      _findInterceptorsClass('JSMutableIndexable');

  late final ClassEntity jsMutableArrayClass =
      _findInterceptorsClass('JSMutableArray');

  late final ClassEntity jsFixedArrayClass =
      _findInterceptorsClass('JSFixedArray');

  late final ClassEntity jsExtendableArrayClass =
      _findInterceptorsClass('JSExtendableArray');

  late final ClassEntity jsUnmodifiableArrayClass =
      _findInterceptorsClass('JSUnmodifiableArray');

  late final ClassEntity jsPositiveIntClass =
      _findInterceptorsClass('JSPositiveInt');

  late final ClassEntity jsUInt32Class = _findInterceptorsClass('JSUInt32');

  late final ClassEntity jsUInt31Class = _findInterceptorsClass('JSUInt31');

  /// Returns `true` member is the 'findIndexForNativeSubclassType' method
  /// declared in `dart:_interceptors`.
  bool isFindIndexForNativeSubclassType(MemberEntity member) {
    return member.name == 'findIndexForNativeSubclassType' &&
        member.isTopLevel &&
        member.library == interceptorsLibrary;
  }

  late final FunctionEntity getNativeInterceptorMethod =
      _findInterceptorsFunction('getNativeInterceptor');

  late final ConstructorEntity jsArrayTypedConstructor =
      _env.lookupConstructor(jsArrayClass, 'typed')!;

  // From dart:_js_helper
  // TODO(johnniwinther): Avoid the need for this (from [CheckedModeHelper]).
  FunctionEntity findHelperFunction(String name) => _findHelperFunction(name);

  FunctionEntity _findHelperFunction(String name) =>
      _findLibraryMember(jsHelperLibrary, name)!;

  ClassEntity _findHelperClass(String name) =>
      _findClass(jsHelperLibrary, name);

  FunctionEntity _findLateHelperFunction(String name) =>
      _findLibraryMember(lateHelperLibrary, name)!;

  late final ClassEntity closureClass = _findHelperClass('Closure');

  late final ClassEntity closureClass0Args = _findHelperClass('Closure0Args');

  late final ClassEntity closureClass2Args = _findHelperClass('Closure2Args');

  late final ClassEntity boundClosureClass = _findHelperClass('BoundClosure');

  late final ClassEntity typeLiteralClass = _findRtiClass('_Type');

  late final ClassEntity constMapLiteralClass = _findHelperClass('ConstantMap');

  late final ClassEntity constSetLiteralClass = _findHelperClass('ConstantSet');

  /// Base class for all records.
  late final ClassEntity recordBaseClass = _findHelperClass('_Record');

  /// A function that is used to model the back-end impacts of record lowering
  /// in the front-end.
  late final FunctionEntity recordImpactModel =
      _findHelperFunction('_recordImpactModel');

  /// Base class for records with N fields. Can be a fixed-arity class or a
  /// general class that works for any arity.
  ClassEntity recordArityClass(int n) {
    return _findClassOrNull(jsHelperLibrary, '_Record$n') ??
        (n == 0 ? emptyRecordClass : recordGeneralBaseClass);
  }

  late final ClassEntity recordGeneralBaseClass = _findHelperClass('_RecordN');

  late final ClassEntity emptyRecordClass = _findHelperClass('_EmptyRecord');

  late final FunctionEntity recordTestByListHelper =
      _findHelperFunction('_testRecordValues');

  late final ClassEntity jsInvocationMirrorClass =
      _findHelperClass('JSInvocationMirror');

  late final ClassEntity requiredSentinelClass = _findHelperClass('_Required');

  InterfaceType get requiredSentinelType => _getRawType(requiredSentinelClass);

  late final MemberEntity invocationTypeArgumentGetter =
      _findClassMember(jsInvocationMirrorClass, 'typeArguments');

  /// Interface used to determine if an object has the JavaScript
  /// indexing behavior. The interface is only visible to specific libraries.
  late final ClassEntity jsIndexingBehaviorInterface =
      _findHelperClass('JavaScriptIndexingBehavior');

  late final ClassEntity stackTraceHelperClass =
      _findHelperClass('_StackTrace');

  late final ClassEntity constantMapClass =
      _findHelperClass(constant_system.JavaScriptMapConstant.DART_CLASS);

  late final ClassEntity constantStringMapClass =
      _findHelperClass(constant_system.JavaScriptMapConstant.DART_STRING_CLASS);

  late final ClassEntity generalConstantMapClass = _findHelperClass(
      constant_system.JavaScriptMapConstant.DART_GENERAL_CLASS);

  late final ClassEntity constantStringSetClass =
      _findHelperClass(constant_system.JavaScriptSetConstant.DART_STRING_CLASS);

  late final ClassEntity generalConstantSetClass = _findHelperClass(
      constant_system.JavaScriptSetConstant.DART_GENERAL_CLASS);

  late final ClassEntity annotationCreatesClass = _findHelperClass('Creates');

  late final ClassEntity annotationReturnsClass = _findHelperClass('Returns');

  late final ClassEntity annotationJSNameClass = _findHelperClass('JSName');

  /// The class for native annotations defined in dart:_js_helper.
  late final ClassEntity nativeAnnotationClass = _findHelperClass('Native');

  bool isAssertTest(MemberEntity member) =>
      member.name == 'assertTest' &&
      member.isFunction &&
      member.isTopLevel &&
      member.library == jsHelperLibrary;

  late final assertTest = _findHelperFunction('assertTest');

  late final assertThrow = _findHelperFunction('assertThrow');

  bool isAssertHelper(MemberEntity member) =>
      member.name == 'assertHelper' &&
      member.isFunction &&
      member.isTopLevel &&
      member.library == jsHelperLibrary;

  late final assertHelper = _findHelperFunction('assertHelper');

  late final assertUnreachableMethod = _findHelperFunction('assertUnreachable');

  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
  /// loaded.
  late final getIsolateAffinityTagMarker =
      _findHelperFunction('getIsolateAffinityTag');

  /// Holds the method "requiresPreamble" in _js_helper.
  late final requiresPreambleMarker = _findHelperFunction('requiresPreamble');

  /// Holds the method "_rawStartupMetrics" in _js_helper.
  late final rawStartupMetrics = _findHelperFunction('rawStartupMetrics');

  FunctionEntity get loadDeferredLibrary =>
      _findHelperFunction("loadDeferredLibrary");

  FunctionEntity get boolConversionCheck =>
      _findHelperFunction('boolConversionCheck');

  FunctionEntity get traceHelper => _findHelperFunction('traceHelper');

  FunctionEntity get closureFromTearOff =>
      _findHelperFunction('closureFromTearOff');

  FunctionEntity get isJsIndexable => _findHelperFunction('isJsIndexable');

  FunctionEntity get throwIllegalArgumentException =>
      _findHelperFunction('iae');

  FunctionEntity get throwIndexOutOfRangeException =>
      _findHelperFunction('ioore');

  FunctionEntity get exceptionUnwrapper =>
      _findHelperFunction('unwrapException');

  FunctionEntity get throwUnsupportedError =>
      _findHelperFunction('throwUnsupportedError');

  FunctionEntity get throwTypeError => _findRtiFunction('throwTypeError');

  /// Recognizes the `checkConcurrentModificationError` helper without needing
  /// it to be resolved.
  bool isCheckConcurrentModificationError(MemberEntity member) {
    return member.name == 'checkConcurrentModificationError' &&
        member.isFunction &&
        member.isTopLevel &&
        member.library == jsHelperLibrary;
  }

  late final FunctionEntity checkConcurrentModificationError =
      _findHelperFunction('checkConcurrentModificationError');

  FunctionEntity get throwConcurrentModificationError =>
      _findHelperFunction('throwConcurrentModificationError');

  FunctionEntity get stringInterpolationHelper => _findHelperFunction('S');

  FunctionEntity get wrapExceptionHelper =>
      _findHelperFunction('wrapException');

  FunctionEntity get throwExpressionHelper =>
      _findHelperFunction('throwExpression');

  FunctionEntity get closureConverter =>
      _findHelperFunction('convertDartClosureToJS');

  FunctionEntity get traceFromException =>
      _findHelperFunction('getTraceFromException');

  FunctionEntity get checkDeferredIsLoaded =>
      _findHelperFunction('checkDeferredIsLoaded');

  FunctionEntity get createRuntimeType => _findRtiFunction('createRuntimeType');

  FunctionEntity get createInvocationMirror =>
      _findHelperFunction('createInvocationMirror');

  FunctionEntity get createUnmangledInvocationMirror =>
      _findHelperFunction('createUnmangledInvocationMirror');

  FunctionEntity get cyclicThrowHelper =>
      _findHelperFunction("throwCyclicInit");

  FunctionEntity get throwUnsupportedOperation =>
      _findHelperFunction('throwUnsupportedOperation');

  FunctionEntity get defineProperty => _findHelperFunction('defineProperty');

  FunctionEntity get throwLateFieldNI =>
      _findLateHelperFunction('throwLateFieldNI');

  FunctionEntity get throwLateFieldAI =>
      _findLateHelperFunction('throwLateFieldAI');

  FunctionEntity get throwLateFieldADI =>
      _findLateHelperFunction('throwLateFieldADI');

  FunctionEntity get throwUnnamedLateFieldNI =>
      _findLateHelperFunction('throwUnnamedLateFieldNI');

  FunctionEntity get throwUnnamedLateFieldAI =>
      _findLateHelperFunction('throwUnnamedLateFieldAI');

  FunctionEntity get throwUnnamedLateFieldADI =>
      _findLateHelperFunction('throwUnnamedLateFieldADI');

  bool isExtractTypeArguments(FunctionEntity member) {
    return member.name == 'extractTypeArguments' &&
        member.library == internalLibrary;
  }

  // TODO(johnniwinther,sra): Support arbitrary type argument count.
  void _checkTypeArgumentCount(int typeArgumentCount) {
    assert(typeArgumentCount > 0);
    if (typeArgumentCount > 20) {
      failedAt(
          NO_LOCATION_SPANNABLE,
          "Unsupported instantiation argument count: "
          "${typeArgumentCount}");
    }
  }

  ClassEntity getInstantiationClass(int typeArgumentCount) {
    _checkTypeArgumentCount(typeArgumentCount);
    return _findHelperClass('Instantiation$typeArgumentCount');
  }

  FunctionEntity getInstantiateFunction(int typeArgumentCount) {
    _checkTypeArgumentCount(typeArgumentCount);
    return _findHelperFunction('instantiate$typeArgumentCount');
  }

  FunctionEntity get convertMainArgumentList =>
      _findHelperFunction('convertMainArgumentList');

  // From dart:_rti

  ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name);

  FunctionEntity _findRtiFunction(String name) =>
      _findLibraryMember(rtiLibrary, name)!;

  late final FunctionEntity interopNullAssertion =
      _findRtiFunction('_interopNullAssertion');

  late final FunctionEntity setArrayType = _findRtiFunction('_setArrayType');

  late final FunctionEntity findType = _findRtiFunction('findType');

  late final FunctionEntity instanceType = _findRtiFunction('instanceType');

  late final FunctionEntity arrayInstanceType =
      _findRtiFunction('_arrayInstanceType');

  late final FunctionEntity simpleInstanceType =
      _findRtiFunction('_instanceType');

  late final FunctionEntity typeLiteralMaker = _findRtiFunction('typeLiteral');

  late final FunctionEntity checkTypeBound = _findRtiFunction('checkTypeBound');

  late final FunctionEntity pairwiseIsTest = _findRtiFunction('pairwiseIsTest');

  ClassEntity get _rtiImplClass => _findRtiClass('Rti');

  ClassEntity get _rtiUniverseClass => _findRtiClass('_Universe');

  FieldEntity _findRtiClassField(String name) =>
      _findClassMember(_rtiImplClass, name);

  late final FieldEntity rtiAsField = _findRtiClassField('_as');

  late final FieldEntity rtiIsField = _findRtiClassField('_is');

  late final FieldEntity rtiRestField = _findRtiClassField('_rest');

  late final FieldEntity rtiPrecomputed1Field =
      _findRtiClassField('_precomputed1');

  late final FunctionEntity rtiEvalMethod =
      _findClassMember(_rtiImplClass, '_eval');

  late final FunctionEntity rtiBindMethod =
      _findClassMember(_rtiImplClass, '_bind');

  late final FunctionEntity rtiAddRulesMethod =
      _findClassMember(_rtiUniverseClass, 'addRules');

  late final FunctionEntity rtiAddErasedTypesMethod =
      _findClassMember(_rtiUniverseClass, 'addErasedTypes');

  late final FunctionEntity rtiAddTypeParameterVariancesMethod =
      _findClassMember(_rtiUniverseClass, 'addTypeParameterVariances');

  FunctionEntity get installSpecializedIsTest =>
      _findRtiFunction('_installSpecializedIsTest');

  FunctionEntity get installSpecializedAsCheck =>
      _findRtiFunction('_installSpecializedAsCheck');

  late final FunctionEntity generalIsTestImplementation =
      _findRtiFunction('_generalIsTestImplementation');

  late final FunctionEntity generalNullableIsTestImplementation =
      _findRtiFunction('_generalNullableIsTestImplementation');

  late final FunctionEntity generalAsCheckImplementation =
      _findRtiFunction('_generalAsCheckImplementation');

  late final FunctionEntity generalNullableAsCheckImplementation =
      _findRtiFunction('_generalNullableAsCheckImplementation');

  late final FunctionEntity specializedIsObject = _findRtiFunction('_isObject');

  late final FunctionEntity specializedAsObject = _findRtiFunction('_asObject');

  FunctionEntity get specializedIsTop => _findRtiFunction('_isTop');

  FunctionEntity get specializedAsTop => _findRtiFunction('_asTop');

  FunctionEntity get specializedIsBool => _findRtiFunction('_isBool');

  FunctionEntity get specializedAsBool => _findRtiFunction('_asBool');

  FunctionEntity get specializedAsBoolLegacy => _findRtiFunction('_asBoolS');

  FunctionEntity get specializedAsBoolNullable => _findRtiFunction('_asBoolQ');

  FunctionEntity get specializedAsDouble => _findRtiFunction('_asDouble');

  FunctionEntity get specializedAsDoubleLegacy =>
      _findRtiFunction('_asDoubleS');

  FunctionEntity get specializedAsDoubleNullable =>
      _findRtiFunction('_asDoubleQ');

  FunctionEntity get specializedIsInt => _findRtiFunction('_isInt');

  FunctionEntity get specializedAsInt => _findRtiFunction('_asInt');

  FunctionEntity get specializedAsIntLegacy => _findRtiFunction('_asIntS');

  FunctionEntity get specializedAsIntNullable => _findRtiFunction('_asIntQ');

  FunctionEntity get specializedIsNum => _findRtiFunction('_isNum');

  FunctionEntity get specializedAsNum => _findRtiFunction('_asNum');

  FunctionEntity get specializedAsNumLegacy => _findRtiFunction('_asNumS');

  FunctionEntity get specializedAsNumNullable => _findRtiFunction('_asNumQ');

  FunctionEntity get specializedIsString => _findRtiFunction('_isString');

  FunctionEntity get specializedAsString => _findRtiFunction('_asString');

  FunctionEntity get specializedAsStringLegacy =>
      _findRtiFunction('_asStringS');

  FunctionEntity get specializedAsStringNullable =>
      _findRtiFunction('_asStringQ');

  FunctionEntity get instantiatedGenericFunctionTypeNewRti =>
      _findRtiFunction('instantiatedGenericFunctionType');

  FunctionEntity get closureFunctionType =>
      _findRtiFunction('closureFunctionType');

  // From dart:_internal

  late final ClassEntity symbolImplementationClass =
      _findClass(internalLibrary, 'Symbol');

  /// Used to annotate items that have the keyword "native".
  late final ClassEntity externalNameClass =
      _findClass(internalLibrary, 'ExternalName');

  InterfaceType get externalNameType => _getRawType(externalNameClass);

  // From dart:_js_embedded_names

  late final ClassEntity jsGetNameEnum =
      _findClass(sharedEmbeddedNamesLibrary, 'JsGetName');

  /// Returns `true` if [member] is a "foreign helper", that is, a member whose
  /// semantics is defined synthetically and not through Dart code.
  ///
  /// Most foreign helpers are located in the `dart:_foreign_helper` library.
  bool isForeignHelper(MemberEntity member) {
    return member.library == foreignLibrary ||
        isLateReadCheck(member) ||
        isLateWriteOnceCheck(member) ||
        isLateInitializeOnceCheck(member) ||
        isCreateInvocationMirrorHelper(member);
  }

  bool _isTopLevelFunctionNamed(String name, MemberEntity member) =>
      member.name == name && member.isFunction && member.isTopLevel;

  /// Returns `true` if [member] is the `createJsSentinel` function defined in
  /// dart:_foreign_helper.
  bool isCreateJsSentinel(MemberEntity member) =>
      member.library == foreignLibrary &&
      _isTopLevelFunctionNamed('createJsSentinel', member);

  /// Returns `true` if [member] is the `isJsSentinel` function defined in
  /// dart:_foreign_helper.
  bool isIsJsSentinel(MemberEntity member) =>
      member.library == foreignLibrary &&
      _isTopLevelFunctionNamed('isJsSentinel', member);

  /// Returns `true` if [member] is the `_lateReadCheck` function defined in
  /// dart:_late_helper.
  bool isLateReadCheck(MemberEntity member) =>
      member.library == lateHelperLibrary &&
      _isTopLevelFunctionNamed('_lateReadCheck', member);

  /// Returns `true` if [member] is the `_lateWriteOnceCheck` function defined
  /// in dart:_late_helper.
  bool isLateWriteOnceCheck(MemberEntity member) =>
      member.library == lateHelperLibrary &&
      _isTopLevelFunctionNamed('_lateWriteOnceCheck', member);

  /// Returns `true` if [member] is the `_lateInitializeOnceCheck` function
  /// defined in dart:_late_helper.
  bool isLateInitializeOnceCheck(MemberEntity member) =>
      member.library == lateHelperLibrary &&
      _isTopLevelFunctionNamed('_lateInitializeOnceCheck', member);

  /// Returns `true` if [member] is the `createSentinel` function defined in
  /// dart:_internal.
  bool isCreateSentinel(MemberEntity member) =>
      member.library == internalLibrary &&
      _isTopLevelFunctionNamed('createSentinel', member);

  /// Returns `true` if [member] is the `isSentinel` function defined in
  /// dart:_internal.
  bool isIsSentinel(MemberEntity member) =>
      member.library == internalLibrary &&
      _isTopLevelFunctionNamed('isSentinel', member);

  /// Returns `true` if [member] is the `allowInterop` function defined in
  /// dart:js_util.
  bool isAllowInterop(MemberEntity member) =>
      member.library == dartJsUtilLibrary &&
      _isTopLevelFunctionNamed('allowInterop', member);

  ClassEntity getDefaultSuperclass(
      ClassEntity cls, NativeBasicData nativeBasicData) {
    final defaultedClass = defaultReceiverClass(this, nativeBasicData, cls);
    if (defaultedClass != cls) return defaultedClass;
    // Native classes inherit from Interceptor.
    return nativeBasicData.isNativeClass(cls)
        ? jsInterceptorClass
        : objectClass;
  }

  // From dart:js_util
  late final FunctionEntity? jsAllowInterop =
      _findLibraryMember(dartJsUtilLibrary, 'allowInterop', required: false);

  bool isCreateInvocationMirrorHelper(MemberEntity member) {
    return member.isTopLevel &&
        member.name == '_createInvocationMirror' &&
        member.library == coreLibrary;
  }
}

class KCommonElements extends CommonElements {
  KCommonElements(super.dartTypes, super.env);

  // From package:js

  late final ClassEntity? jsAnnotationClass1 =
      _findClassOrNull(packageJsLibrary, 'JS');

  late final ClassEntity? jsAnonymousClass1 =
      _findClassOrNull(packageJsLibrary, '_Anonymous');

  // From dart:_js_annotations

  late final ClassEntity? jsAnnotationClass2 =
      _findClassOrNull(dartJsAnnotationsLibrary, 'JS');

  late final ClassEntity? jsAnonymousClass2 =
      _findClassOrNull(dartJsAnnotationsLibrary, '_Anonymous');

  // From dart:js_interop

  late final ClassEntity? jsAnnotationClass3 =
      _findClassOrNull(dartJsInteropLibrary, 'JS');

  /// Returns `true` if [cls] is a @JS() annotation.
  ///
  /// The class can come from either `package:js`, `dart:_js_annotations`, or
  /// `dart:js_interop`.
  bool isJsAnnotationClass(ClassEntity cls) {
    return cls == jsAnnotationClass1 ||
        cls == jsAnnotationClass2 ||
        cls == jsAnnotationClass3;
  }

  /// Returns `true` if [cls] is an @anonymous annotation.
  ///
  /// The class can come from either `package:js` or `dart:_js_annotations`.
  bool isJsAnonymousClass(ClassEntity cls) {
    return cls == jsAnonymousClass1 || cls == jsAnonymousClass2;
  }

  late final ClassEntity pragmaClass = _findClass(coreLibrary, 'pragma');

  late final FieldEntity pragmaClassNameField =
      _findClassMember(pragmaClass, 'name');

  late final FieldEntity pragmaClassOptionsField =
      _findClassMember(pragmaClass, 'options');
}

class JCommonElements extends CommonElements {
  JCommonElements(super.dartTypes, super.env);

  /// Returns `true` if [element] is the named constructor of `List`,
  /// e.g. `List.of`.
  ///
  /// This will not resolve the constructor if it hasn't been seen yet during
  /// compilation.
  bool isNamedListConstructor(String name, ConstructorEntity element) =>
      element.name == name && element.enclosingClass == listClass;

  /// Returns `true` if [element] is the named constructor of `JSArray`,
  /// e.g. `JSArray.fixed`.
  ///
  /// This will not resolve the constructor if it hasn't been seen yet during
  /// compilation.
  bool isNamedJSArrayConstructor(String name, ConstructorEntity element) =>
      element.name == name && element.enclosingClass == jsArrayClass;

  bool isDefaultEqualityImplementation(MemberEntity element) {
    assert(element.name == '==');
    ClassEntity? classElement = element.enclosingClass;
    return classElement == objectClass ||
        classElement == jsInterceptorClass ||
        classElement == jsNullClass;
  }

  /// Returns `true` if [selector] applies to `JSIndexable.length`.
  bool appliesToJsIndexableLength(Selector selector) {
    return selector.name == 'length' && (selector.isGetter || selector.isCall);
  }

  late final FunctionEntity jsArrayRemoveLast =
      _findClassMember(jsArrayClass, 'removeLast');

  late final FunctionEntity jsArrayAdd = _findClassMember(jsArrayClass, 'add');

  bool _isJsStringClass(ClassEntity cls) {
    return cls.name == 'JSString' && cls.library == interceptorsLibrary;
  }

  bool isJsStringSplit(MemberEntity member) {
    return member.name == 'split' &&
        member.isInstanceMember &&
        _isJsStringClass(member.enclosingClass!);
  }

  /// Returns `true` if [selector] applies to `JSString.split` on [receiver]
  /// in the given [world].
  ///
  /// Returns `false` if `JSString.split` is not available (e.g. the
  /// method was tree-shaken in an earlier compilation phase).
  bool appliesToJsStringSplit(Selector selector, AbstractValue? receiver,
      AbstractValueDomain abstractValueDomain) {
    final splitMember = jsStringSplit;
    if (splitMember == null) return false;
    return selector.applies(splitMember) &&
        (receiver == null ||
            abstractValueDomain
                .isTargetingMember(receiver, splitMember, selector.memberName)
                .isPotentiallyTrue);
  }

  late final FunctionEntity? jsStringSplit =
      _findClassMemberOrNull(jsStringClass, 'split');

  late final FunctionEntity jsStringToString =
      _findClassMember(jsStringClass, 'toString');

  late final FunctionEntity jsStringOperatorAdd =
      _findClassMember(jsStringClass, '+');

  late final ClassEntity jsConstClass = _findClass(foreignLibrary, 'JS_CONST');

  /// Return `true` if [member] is the 'checkInt' function defined in
  /// dart:_js_helpers.
  bool isCheckInt(MemberEntity member) {
    return member.isFunction &&
        member.isTopLevel &&
        member.library == jsHelperLibrary &&
        member.name == 'checkInt';
  }

  /// Return `true` if [member] is the 'checkNum' function defined in
  /// dart:_js_helpers.
  bool isCheckNum(MemberEntity member) {
    return member.isFunction &&
        member.isTopLevel &&
        member.library == jsHelperLibrary &&
        member.name == 'checkNum';
  }

  /// Return `true` if [member] is the 'checkString' function defined in
  /// dart:_js_helpers.
  bool isCheckString(MemberEntity member) {
    return member.isFunction &&
        member.isTopLevel &&
        member.library == jsHelperLibrary &&
        member.name == 'checkString';
  }

  bool isInstantiationClass(ClassEntity cls) {
    return cls.library == jsHelperLibrary &&
        cls.name != 'Instantiation' &&
        cls.name.startsWith('Instantiation');
  }

  // From dart:_native_typed_data

  late final ClassEntity? typedArrayOfIntClass =
      _findClass(typedDataLibrary, 'NativeTypedArrayOfInt');

  late final ClassEntity typedArrayOfDoubleClass =
      _findClass(typedDataLibrary, 'NativeTypedArrayOfDouble');

  late final ClassEntity jsBuiltinEnum =
      _findClass(sharedEmbeddedNamesLibrary, 'JsBuiltin');

  bool isForeign(MemberEntity element) => element.library == foreignLibrary;

  /// Returns `true` if the implementation of the 'operator ==' [function] is
  /// known to handle `null` as argument.
  bool operatorEqHandlesNullArgument(FunctionEntity function) {
    assert(function.name == '==',
        failedAt(function, "Unexpected function $function."));
    ClassEntity? cls = function.enclosingClass;
    return cls == objectClass ||
        cls == jsInterceptorClass ||
        cls == jsNullClass;
  }
}

/// Interface for accessing libraries, classes and members.
///
/// The element environment makes private and injected members directly
/// available and should therefore not be used to determine scopes.
///
/// The properties exposed are Dart-centric and should therefore, long-term, not
/// be used during codegen, expect for mirrors.
// TODO(johnniwinther): Split this into an element environment and a type query
// interface, the first should only be used during resolution and the latter in
// both resolution and codegen.
abstract class ElementEnvironment {
  IrToElementMap get elementMap;

  /// Returns the main library for the compilation.
  LibraryEntity? get mainLibrary;

  /// Returns the main method for the compilation.
  FunctionEntity? get mainFunction;

  /// Returns all known libraries.
  Iterable<LibraryEntity> get libraries;

  /// Returns the library name of [library] or '' if the library is unnamed.
  String getLibraryName(LibraryEntity library);

  /// Lookup the library with the canonical [uri], fail if the library is
  /// missing and [required];
  LibraryEntity? lookupLibrary(Uri uri, {bool required = false});

  /// Calls [f] for every class declared in [library].
  void forEachClass(LibraryEntity library, void f(ClassEntity cls));

  /// Lookup the class [name] in [library], fail if the class is missing and
  /// [required].
  ClassEntity? lookupClass(LibraryEntity library, String name,
      {bool required = false});

  /// Calls [f] for every top level member in [library].
  void forEachLibraryMember(LibraryEntity library, void f(MemberEntity member));

  /// Lookup the member [name] in [library], fail if the class is missing and
  /// [required].
  MemberEntity? lookupLibraryMember(LibraryEntity library, String name,
      {bool setter = false, bool required = false});

  /// Lookup the member [name] in [cls], fail if the class is missing and
  /// [required].
  MemberEntity? lookupLocalClassMember(ClassEntity cls, Name name,
      {bool required = false});

  /// Lookup the member [name] in [cls] and its superclasses.
  ///
  /// Return `null` if the member is not found in the class or any superclass.
  MemberEntity? lookupClassMember(ClassEntity cls, Name name) {
    ClassEntity? clsLocal = cls;
    while (clsLocal != null) {
      final entity = lookupLocalClassMember(clsLocal, name);
      if (entity != null) return entity;

      clsLocal = getSuperClass(clsLocal);
    }
    return null;
  }

  /// Lookup the constructor [name] in [cls], fail if the class is missing and
  /// [required].
  ConstructorEntity? lookupConstructor(ClassEntity cls, String name,
      {bool required = false});

  /// Calls [f] for each class member declared in [cls].
  void forEachLocalClassMember(ClassEntity cls, void f(MemberEntity member));

  /// Calls [f] for each class member declared or inherited in [cls] together
  /// with the class that declared the member.
  ///
  /// TODO(johnniwinther): This should not include static members of
  /// superclasses.
  void forEachClassMember(
      ClassEntity cls, void f(ClassEntity declarer, MemberEntity member));

  /// Calls [f] for every constructor declared in [cls].
  ///
  /// Will ensure that the class and all constructors are resolved if
  /// [ensureResolved] is `true`.
  void forEachConstructor(
      ClassEntity cls, void f(ConstructorEntity constructor));

  /// Returns the superclass of [cls].
  ///
  /// If [skipUnnamedMixinApplications] is `true`, unnamed mixin applications
  /// are excluded, for instance for these classes
  ///
  ///     class S {}
  ///     class M {}
  ///     class C extends S with M {}
  ///
  /// the result of `getSuperClass(C)` is the unnamed mixin application
  /// typically named `S+M` and `getSuperClass(S+M)` is `S`, whereas
  /// the result of `getSuperClass(C, skipUnnamedMixinApplications: false)` is
  /// `S`.
  ClassEntity? getSuperClass(ClassEntity cls,
      {bool skipUnnamedMixinApplications = false});

  /// Calls [f] for each supertype of [cls].
  void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype));

  /// Calls [f] for each SuperClass of [cls].
  void forEachSuperClass(ClassEntity cls, void f(ClassEntity superClass)) {
    for (var superClass = getSuperClass(cls);
        superClass != null;
        superClass = getSuperClass(superClass)) {
      f(superClass);
    }
  }

  /// Create the instantiation of [cls] with the given [typeArguments] and
  /// [nullability].
  InterfaceType createInterfaceType(
      ClassEntity cls, List<DartType> typeArguments);

  /// Returns the `dynamic` type.
  DartType get dynamicType;

  /// Returns the 'raw type' of [cls]. That is, the instantiation of [cls]
  /// where all types arguments are `dynamic`.
  InterfaceType getRawType(ClassEntity cls);

  /// Returns the 'JS-interop type' of [cls]; that is, the instantiation of
  /// [cls] where all type arguments are 'any'.
  InterfaceType getJsInteropType(ClassEntity cls);

  /// Returns the 'this type' of [cls]. That is, the instantiation of [cls]
  /// where the type arguments are the type variables of [cls].
  InterfaceType getThisType(ClassEntity cls);

  /// Returns the instantiation of [cls] to bounds.
  InterfaceType getClassInstantiationToBounds(ClassEntity cls);

  /// Returns `true` if [cls] is generic.
  bool isGenericClass(ClassEntity cls);

  /// Returns `true` if [cls] is a mixin application (named or unnamed).
  bool isMixinApplication(ClassEntity cls);

  /// Returns `true` if [cls] is an unnamed mixin application.
  bool isUnnamedMixinApplication(ClassEntity cls);

  /// The upper bound on the [typeVariable]. If not explicitly declared, this is
  /// `Object`.
  DartType getTypeVariableBound(TypeVariableEntity typeVariable);

  /// Returns the variances for each type parameter in [cls].
  List<Variance> getTypeVariableVariances(ClassEntity cls);

  /// Returns the type of [function].
  FunctionType getFunctionType(FunctionEntity function);

  /// Returns the function type variables defined on [function].
  List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function);

  /// Returns the type of the [local] function.
  FunctionType getLocalFunctionType(Local local);

  /// Returns the type of [field].
  DartType getFieldType(FieldEntity field);

  /// Returns `true` if [cls] is a Dart enum class.
  bool isEnumClass(ClassEntity cls);

  /// Returns the 'effective' mixin class if [cls] is a mixin application, and
  /// `null` otherwise.
  ///
  /// The 'effective' mixin class is the class from which members are mixed in.
  /// Normally this is the mixin class itself, but not if the mixin class itself
  /// is a mixin application.
  ///
  /// Consider this hierarchy:
  ///
  ///     class A {}
  ///     class B = Object with A {}
  ///     class C = Object with B {}
  ///
  /// The mixin classes of `B` and `C` are `A` and `B`, respectively, but the
  /// _effective_ mixin class of both is `A`.
  ClassEntity? getEffectiveMixinClass(ClassEntity cls);
}

abstract class KElementEnvironment extends ElementEnvironment {
  /// Calls [f] for each class that is mixed into [cls] or one of its
  /// superclasses.
  void forEachMixin(ClassEntity cls, void f(ClassEntity mixin));

  /// Returns the imports seen in [library]
  Iterable<ImportEntity> getImports(LibraryEntity library);

  /// Returns the metadata constants declared on [member].
  Iterable<ConstantValue> getMemberMetadata(MemberEntity member,
      {bool includeParameterMetadata = false});

  /// `true` if field is the backing field for a `late` or `late final` instance
  /// field.
  bool isLateBackingField(FieldEntity field);

  /// `true` if field is the backing field for a `late final` instance field. If
  /// this is true, so is [isLateBackingField].
  bool isLateFinalBackingField(FieldEntity field);
}

abstract class JElementEnvironment extends ElementEnvironment {
  /// Calls [f] for each class member added to [cls] during compilation.
  void forEachInjectedClassMember(ClassEntity cls, void f(MemberEntity member));

  /// Calls [f] for every constructor body in [cls].
  void forEachConstructorBody(
      ClassEntity cls, void f(ConstructorBodyEntity constructorBody));

  /// Calls [f] for each nested closure in [member].
  void forEachNestedClosure(
      MemberEntity member, void f(FunctionEntity closure));

  /// Returns `true` if [cls] is a mixin application with its own members.
  ///
  /// This occurs when a mixin contains methods with super calls or when
  /// the mixin application contains concrete forwarding stubs.
  bool isMixinApplicationWithMembers(ClassEntity cls);

  /// The default type of the [typeVariable].
  ///
  /// This is the type used as the default type argument when no explicit type
  /// argument is passed.
  DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable);

  /// Returns the 'element' type of a [function] with the async, async* or sync*
  /// marker. [returnType] is the return type of the marked function.
  DartType getAsyncOrSyncStarElementType(
      FunctionEntity function, DartType returnType);

  /// Returns the 'element' type of a function with an async, async* or sync*
  /// marker. The return type of the method is inspected to determine the type
  /// parameter of the Future, Stream or Iterable.
  DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function);

  /// Calls [f] with every instance field, together with its declarer, in an
  /// instance of [cls]. All fields inherited from superclasses and mixins are
  /// included.
  ///
  /// If [isElided] is `true`, the field is not read and should therefore not
  /// be emitted.
  void forEachInstanceField(
      ClassEntity cls, void f(ClassEntity declarer, FieldEntity field));

  /// Calls [f] with every instance field declared directly in class [cls]
  /// (i.e. no inherited fields). Fields are presented in initialization
  /// (i.e. textual) order.
  ///
  /// If [isElided] is `true`, the field is not read and should therefore not
  /// be emitted.
  void forEachDirectInstanceField(ClassEntity cls, void f(FieldEntity field));

  /// Calls [f] for each parameter of [function] providing the type and name of
  /// the parameter and the [defaultValue] if the parameter is optional.
  void forEachParameter(covariant FunctionEntity function,
      void f(DartType type, String? name, ConstantValue? defaultValue));

  /// Calls [f] for each parameter - given as a [Local] - of [function].
  void forEachParameterAsLocal(GlobalLocalsMap globalLocalsMap,
      FunctionEntity function, void f(Local parameter));
}
