// 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 '../common.dart';
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart';
import '../js_backend/native_data_interfaces.dart' show NativeBasicData;
import '../js_model/locals.dart';
import '../universe/selector.dart' show Selector;

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 `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(_env.lookupLibrary(Uris.dart_collection), '_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: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);

  /// 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 library.
  late final LibraryEntity? dartJsLibrary = _env.lookupLibrary(Uris.dart_js);

  /// 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 `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 ??=
        _findConstructor(symbolImplementationClass, '');
  }

  void _ensureSymbolConstructorDependencies() {
    if (_computedSymbolConstructorDependencies) return;
    _computedSymbolConstructorDependencies = true;
    if (_symbolConstructorTarget == null) {
      if (_symbolImplementationClass == null) {
        _symbolImplementationClass =
            _findClass(internalLibrary, 'Symbol', required: false);
      }
      if (_symbolImplementationClass != null) {
        _symbolConstructorTarget =
            _findConstructor(_symbolImplementationClass!, '', required: false);
      }
    }
    if (_symbolClass == null) {
      _symbolClass = _findClass(coreLibrary, 'Symbol', required: false);
    }
    if (_symbolClass == null) {
      return;
    }
    _symbolConstructorImplementationTarget =
        _findConstructor(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) {
    assert((element as dynamic) != null); // TODO(48820): Remove.
    _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 `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,
      {bool required = true}) {
    if (library == null) return null;
    return _env.lookupClass(library, name, required: required);
  }

  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 _findClassMember<T extends MemberEntity>(ClassEntity cls, String name,
      {bool setter = false, bool required = true}) {
    return _env.lookupLocalClassMember(cls, name,
        setter: setter, required: required) as T;
  }

  ConstructorEntity _findConstructor(ClassEntity cls, String name,
      {bool required = true}) {
    return _env.lookupConstructor(cls, name, required: required);
  }

  /// 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) =>
      dartTypes.treatAsRawType(sourceType)
          ? _env.getRawType(jsArrayClass)
          : _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);

  InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
      {bool onlyStringKeys = false}) {
    ClassEntity classElement =
        onlyStringKeys ? constantStringMapClass : generalConstantMapClass;
    if (dartTypes.treatAsRawType(sourceType)) {
      return _env.getRawType(classElement);
    } else {
      return _env.createInterfaceType(classElement, sourceType.typeArguments);
    }
  }

  InterfaceType getConstantSetTypeFor(InterfaceType sourceType) =>
      dartTypes.treatAsRawType(sourceType)
          ? _env.getRawType(constSetLiteralClass)
          : _env.createInterfaceType(
              constSetLiteralClass, sourceType.typeArguments);

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

  FieldEntity get symbolField => _symbolImplementationField ??=
      _env.lookupLocalClassMember(symbolImplementationClass, '_name',
          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(
            _env.lookupLibrary(Uris.dart_collection), '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, '_makeLiteral')
          as FunctionEntity;
  late final FunctionEntity mapLiteralUntypedEmptyMaker = _env
      .lookupLocalClassMember(mapLiteralClass, '_makeEmpty') as FunctionEntity;

  late final ClassEntity setLiteralClass =
      _findClass(_env.lookupLibrary(Uris.dart_collection), 'LinkedHashSet')!;

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

  late final FunctionEntity objectNoSuchMethod = _env.lookupLocalClassMember(
      objectClass, 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"), "yieldStar") as FunctionEntity;

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

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

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

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

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

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

  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 jsJavaScriptFunctionClass =
      _findInterceptorsClass('JavaScriptFunction');

  InterfaceType get jsJavaScriptFunctionType =>
      _getRawType(jsJavaScriptFunctionClass);

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

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

  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 =
      _findConstructor(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');

  // TODO(fishythefish): Implement a `ConstantSet` class and update the backend
  // impacts + constant emitter accordingly.
  late final ClassEntity constSetLiteralClass = unmodifiableSetClass;

  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 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');

  late final assertTest = _findHelperFunction('assertTest');

  late final assertThrow = _findHelperFunction('assertThrow');

  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 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 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');

  ClassEntity get _rtiImplClass => _findClass(rtiLibrary, 'Rti')!;

  ClassEntity get _rtiUniverseClass => _findClass(rtiLibrary, '_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(
      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
      '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);

  ClassEntity getDefaultSuperclass(
      ClassEntity cls, NativeBasicData nativeBasicData) {
    if (nativeBasicData.isJsInteropClass(cls)) {
      return jsLegacyJavaScriptObjectClass;
    }
    // Native classes inherit from Interceptor.
    return nativeBasicData.isNativeClass(cls)
        ? jsInterceptorClass
        : objectClass;
  }

  // From package:js
  late final FunctionEntity? jsAllowInterop1 =
      _findLibraryMember(dartJsLibrary, 'allowInterop', required: false);

  // From dart:_js_annotations;
  late final FunctionEntity? jsAllowInterop2 = _findLibraryMember(
      dartJsAnnotationsLibrary, 'allowInterop',
      required: false);

  /// Returns `true` if [function] is `allowInterop`.
  ///
  /// This function can come from either `package:js` or `dart:_js_annotations`.
  bool isJsAllowInterop(FunctionEntity function) {
    return function == jsAllowInterop1 || function == jsAllowInterop2;
  }

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

class KCommonElements extends CommonElements {
  KCommonElements(DartTypes dartTypes, ElementEnvironment env)
      : super(dartTypes, env);

  // From package:js

  late final ClassEntity? jsAnnotationClass1 =
      _findClass(packageJsLibrary, 'JS', required: false);

  late final ClassEntity? jsAnonymousClass1 =
      _findClass(packageJsLibrary, '_Anonymous', required: false);

  // From dart:_js_annotations

  late final ClassEntity? jsAnnotationClass2 =
      _findClass(dartJsAnnotationsLibrary, 'JS', required: false);

  late final ClassEntity? jsAnonymousClass2 =
      _findClass(dartJsAnnotationsLibrary, '_Anonymous', required: false);

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

  /// 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 {
  FunctionEntity? _jsStringSplit;

  JCommonElements(DartTypes dartTypes, ElementEnvironment env)
      : super(dartTypes, env);

  /// Returns `true` if [element] is the unnamed constructor of `List`.
  ///
  /// This will not resolve the constructor if it hasn't been seen yet during
  /// compilation.
  bool isUnnamedListConstructor(ConstructorEntity element) =>
      (element.name == '' && element.enclosingClass == listClass) ||
      (element.name == 'list' && element.enclosingClass == jsArrayClass);

  /// 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.
  bool appliesToJsStringSplit(Selector selector, AbstractValue? receiver,
      AbstractValueDomain abstractValueDomain) {
    if (_jsStringSplit == null) {
      ClassEntity? cls =
          _findClass(interceptorsLibrary, 'JSString', required: false);
      if (cls == null) return false;
      _jsStringSplit = _findClassMember(cls, 'split', required: false);
      if (_jsStringSplit == null) return false;
    }
    return selector.applies(_jsStringSplit!) &&
        (receiver == null ||
            abstractValueDomain
                .isTargetingMember(receiver, jsStringSplit, selector.memberName)
                .isPotentiallyTrue);
  }

  FunctionEntity get jsStringSplit =>
      _jsStringSplit ??= _findClassMember(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(
      _env.lookupLibrary(Uris.dart__native_typed_data, required: true),
      'NativeTypedArrayOfInt');

  late final ClassEntity typedArrayOfDoubleClass = _findClass(
      _env.lookupLibrary(Uris.dart__native_typed_data, required: true),
      'NativeTypedArrayOfDouble')!;

  late final ClassEntity jsBuiltinEnum = _findClass(
      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
      '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 {
  /// 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, String name,
      {bool setter = false, 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, String name,
      {bool setter = false}) {
    ClassEntity? clsLocal = cls;
    while (clsLocal != null) {
      final entity = lookupLocalClassMember(clsLocal, name, setter: setter);
      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 [marker]. [returnType] is the return type marked function.
  DartType getAsyncOrSyncStarElementType(
      AsyncMarker marker, 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));
}
