// Copyright (c) 2018, 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 '../../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../../elements/entities.dart';
import '../../elements/names.dart';
import '../../elements/types.dart' show DartType;
import '../../ir/class_relation.dart';
import '../../js_model/js_world.dart';
import '../../serialization/serialization.dart';
import '../../universe/member_hierarchy.dart';
import '../../universe/selector.dart';
import '../../universe/world_builder.dart';
import '../../universe/use.dart';
import '../../world.dart';
import '../abstract_value_domain.dart';
import '../abstract_value_strategy.dart';
import 'powerset_bits.dart';

class PowersetValue implements AbstractValue {
  final AbstractValue _abstractValue;
  final int _powersetBits;
  PowersetValue(this._abstractValue, this._powersetBits);

  AbstractValue get abstractValue => _abstractValue;
  int get powersetBits => _powersetBits;

  @override
  bool operator ==(var other) {
    if (identical(this, other)) return true;
    if (other is! PowersetValue) return false;
    return _abstractValue == other._abstractValue &&
        _powersetBits == other._powersetBits;
  }

  @override
  int get hashCode {
    return _abstractValue.hashCode * _powersetBits.hashCode;
  }

  @override
  String toString() =>
      '${PowersetBitsDomain.toText(_powersetBits, omitIfTop: true)}'
      '${_abstractValue}';
}

AbstractValue? unwrapOrNull(PowersetValue? powerset) {
  return powerset?._abstractValue;
}

PowersetValue? wrapOrNull(AbstractValue? abstractValue, int powersetBits) {
  return abstractValue == null
      ? null
      : PowersetValue(abstractValue, powersetBits);
}

class PowersetDomain with AbstractValueDomain {
  final AbstractValueDomain _abstractValueDomain;
  final PowersetBitsDomain _powersetBitsDomain;

  const PowersetDomain(this._abstractValueDomain, this._powersetBitsDomain);

  PowersetBitsDomain get powersetBitsDomain => _powersetBitsDomain;

  @override
  AbstractValue get internalTopType => PowersetValue(
      _abstractValueDomain.internalTopType,
      _powersetBitsDomain.internalTopType);

  @override
  AbstractValue get dynamicType => PowersetValue(
      _abstractValueDomain.dynamicType, _powersetBitsDomain.dynamicType);

  //TODO(coam)
  @override
  void writeAbstractValueToDataSink(
      DataSinkWriter sink, covariant PowersetValue value) {
    _abstractValueDomain.writeAbstractValueToDataSink(
        sink, value._abstractValue);
  }

  //TODO(coam)
  @override
  AbstractValue readAbstractValueFromDataSource(DataSourceReader source) {
    int powersetBits = _powersetBitsDomain.powersetTop;
    AbstractValue abstractValue =
        _abstractValueDomain.readAbstractValueFromDataSource(source);
    return PowersetValue(abstractValue, powersetBits);
  }

  //TODO(coam)
  @override
  String getCompactText(covariant PowersetValue value) =>
      _abstractValueDomain.getCompactText(value._abstractValue);

  @override
  AbstractBool isFixedLengthJsIndexable(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
          ? AbstractBool.False
          : _abstractValueDomain.isFixedLengthJsIndexable(value._abstractValue);

  @override
  AbstractBool isJsIndexableAndIterable(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
          ? AbstractBool.False
          : _abstractValueDomain.isJsIndexableAndIterable(value._abstractValue);

  @override
  AbstractBool isJsIndexable(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
          ? AbstractBool.False
          : _abstractValueDomain.isJsIndexable(value._abstractValue);

  @override
  MemberEntity? locateSingleMember(
          covariant PowersetValue receiver, Selector selector) =>
      _abstractValueDomain.locateSingleMember(
          receiver._abstractValue, selector);

  @override
  AbstractBool isIn(
          covariant PowersetValue subset, covariant PowersetValue superset) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isIn(
              subset._powersetBits, superset._powersetBits),
          _abstractValueDomain.isIn(
              subset._abstractValue, superset._abstractValue));

  @override
  AbstractBool needsNoSuchMethodHandling(
          covariant PowersetValue receiver, Selector selector) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.needsNoSuchMethodHandling(
              receiver._powersetBits, selector),
          _abstractValueDomain.needsNoSuchMethodHandling(
              receiver._abstractValue, selector));

  @override
  AbstractBool isTargetingMember(
          covariant PowersetValue receiver, MemberEntity member, Name name) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isTargetingMember(
              receiver._powersetBits, member, name),
          _abstractValueDomain.isTargetingMember(
              receiver._abstractValue, member, name));

  @override
  AbstractValue computeReceiver(Iterable<MemberEntity> members) {
    int powersetBits = _powersetBitsDomain.computeReceiver(members);
    AbstractValue abstractValue = _abstractValueDomain.computeReceiver(members);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  PrimitiveConstantValue? getPrimitiveValue(covariant PowersetValue value) =>
      _powersetBitsDomain.getPrimitiveValue(value.powersetBits) ??
      _abstractValueDomain.getPrimitiveValue(value._abstractValue);

  @override
  AbstractValue createPrimitiveValue(
      covariant PowersetValue originalValue, PrimitiveConstantValue value) {
    int powersetBits = _powersetBitsDomain.createPrimitiveValue(value);
    AbstractValue abstractValue = _abstractValueDomain.createPrimitiveValue(
        originalValue._abstractValue, value);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isPrimitiveValue(covariant PowersetValue value) =>
      _powersetBitsDomain.isPrimitiveValue(value.powersetBits) ||
      _abstractValueDomain.isPrimitiveValue(value._abstractValue);

  @override
  MemberEntity? getAllocationElement(covariant PowersetValue value) =>
      _abstractValueDomain.getAllocationElement(value._abstractValue);

  @override
  Object? getAllocationNode(covariant PowersetValue value) =>
      _abstractValueDomain.getAllocationNode(value._abstractValue);

  @override
  AbstractValue getGeneralization(covariant PowersetValue value) {
    int powersetBits = _powersetBitsDomain.powersetTop;
    final abstractValue =
        _abstractValueDomain.getGeneralization(unwrapOrNull(value))!;
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isSpecializationOf(covariant PowersetValue specialization,
          covariant PowersetValue generalization) =>
      _abstractValueDomain.isSpecializationOf(
          specialization._abstractValue, generalization._abstractValue);

  @override
  AbstractValue getDictionaryValueForKey(
      covariant PowersetValue value, String key) {
    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
      return dynamicType;
    }
    AbstractValue abstractValue = _abstractValueDomain.getDictionaryValueForKey(
        value._abstractValue, key);
    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
  }

  @override
  bool containsDictionaryKey(covariant PowersetValue value, String key) =>
      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
      _abstractValueDomain.containsDictionaryKey(value._abstractValue, key);

  @override
  AbstractValue createDictionaryValue(
      covariant PowersetValue originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      covariant PowersetValue key,
      covariant PowersetValue value,
      covariant Map<String, AbstractValue> mappings) {
    final powersetBits = originalValue._powersetBits;
    AbstractValue abstractValue = _abstractValueDomain.createDictionaryValue(
        originalValue._abstractValue,
        allocationNode,
        allocationElement,
        key._abstractValue,
        value._abstractValue, {
      for (var entry in mappings.entries)
        entry.key: (entry.value as PowersetValue)._abstractValue
    });
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isDictionary(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
      _abstractValueDomain.isDictionary(value._abstractValue);

  @override
  AbstractValue getMapValueType(covariant PowersetValue value) {
    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
      return dynamicType;
    }
    AbstractValue abstractValue =
        _abstractValueDomain.getMapValueType(value._abstractValue);
    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
  }

  @override
  AbstractValue getMapKeyType(covariant PowersetValue value) {
    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
      return dynamicType;
    }
    AbstractValue abstractValue =
        _abstractValueDomain.getMapValueType(value._abstractValue);
    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
  }

  @override
  AbstractValue createMapValue(
      covariant PowersetValue originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      covariant PowersetValue key,
      covariant PowersetValue value) {
    int powersetBits = originalValue._powersetBits;
    AbstractValue abstractValue = _abstractValueDomain.createMapValue(
        originalValue._abstractValue,
        allocationNode,
        allocationElement,
        key._abstractValue,
        value._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isMap(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
      _abstractValueDomain.isMap(value._abstractValue);

  @override
  AbstractValue getSetElementType(covariant PowersetValue value) {
    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
      return dynamicType;
    }
    AbstractValue abstractValue =
        _abstractValueDomain.getSetElementType(value._abstractValue);
    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
  }

  @override
  AbstractValue createSetValue(
      covariant PowersetValue originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      covariant PowersetValue elementType) {
    int powersetBits = originalValue._powersetBits;
    AbstractValue abstractValue = _abstractValueDomain.createSetValue(
        originalValue._abstractValue,
        allocationNode,
        allocationElement,
        elementType._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isSet(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
      _abstractValueDomain.isSet(value._abstractValue);

  @override
  int? getContainerLength(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
          ? null
          : _abstractValueDomain.getContainerLength(value._abstractValue);

  @override
  AbstractValue getContainerElementType(covariant PowersetValue value) {
    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
      return dynamicType;
    }
    AbstractValue abstractValue =
        _abstractValueDomain.getContainerElementType(value._abstractValue);
    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
  }

  @override
  AbstractValue createContainerValue(
      covariant PowersetValue originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      covariant PowersetValue elementType,
      int? length) {
    int powersetBits = originalValue._powersetBits;
    AbstractValue abstractValue = _abstractValueDomain.createContainerValue(
        originalValue._abstractValue,
        allocationNode,
        allocationElement,
        elementType._abstractValue,
        length);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  bool isContainer(covariant PowersetValue value) =>
      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
      _abstractValueDomain.isContainer(value._abstractValue);

  // TODO(coam): this can be more precise if we build a ConstantValue visitor
  // that can tell us information about the bits given a ConstantValue
  @override
  AbstractValue computeAbstractValueForConstant(covariant ConstantValue value) {
    int powersetBits =
        _powersetBitsDomain.computeAbstractValueForConstant(value);
    AbstractValue abstractValue =
        _abstractValueDomain.computeAbstractValueForConstant(value);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
    int powersetBits = _powersetBitsDomain.powersetTop;
    final abstractValue =
        _abstractValueDomain.getAbstractValueForNativeMethodParameterType(type);
    return wrapOrNull(abstractValue, powersetBits);
  }

  @override
  AbstractBool containsAll(covariant PowersetValue a) =>
      AbstractBool.strengthen(_powersetBitsDomain.containsAll(a._powersetBits),
          _abstractValueDomain.containsAll(a._abstractValue));

  @override
  AbstractBool areDisjoint(
          covariant PowersetValue a, covariant PowersetValue b) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.areDisjoint(a._powersetBits, b._powersetBits),
          _abstractValueDomain.areDisjoint(a._abstractValue, b._abstractValue));

  @override
  AbstractValue intersection(
      covariant PowersetValue a, covariant PowersetValue b) {
    int powersetBits =
        _powersetBitsDomain.intersection(a._powersetBits, b._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.intersection(a._abstractValue, b._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue unionOfMany(Iterable<AbstractValue> values) {
    PowersetValue result = PowersetValue(
        _abstractValueDomain.emptyType, _powersetBitsDomain.powersetBottom);
    for (final value in values) {
      result = union(result, value as PowersetValue);
    }
    return result;
  }

  @override
  PowersetValue union(covariant PowersetValue a, covariant PowersetValue b) {
    int powersetBits =
        _powersetBitsDomain.union(a._powersetBits, b._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.union(a._abstractValue, b._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractBool isPrimitiveOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPrimitiveOrNull(value._powersetBits),
          _abstractValueDomain.isPrimitiveOrNull(value._abstractValue));

  @override
  AbstractBool isStringOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isStringOrNull(value._powersetBits),
          _abstractValueDomain.isStringOrNull(value._abstractValue));

  @override
  AbstractBool isString(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isString(value._powersetBits),
          _abstractValueDomain.isString(value._abstractValue));

  @override
  AbstractBool isBooleanOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isBooleanOrNull(value._powersetBits),
          _abstractValueDomain.isBooleanOrNull(value._abstractValue));

  @override
  AbstractBool isBoolean(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isBoolean(value._powersetBits),
          _abstractValueDomain.isBoolean(value._abstractValue));

  @override
  AbstractBool isTruthy(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isTruthy(value._powersetBits),
          _abstractValueDomain.isTruthy(value._abstractValue));

  @override
  AbstractBool isNumberOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isNumberOrNull(value._powersetBits),
          _abstractValueDomain.isNumberOrNull(value._abstractValue));

  @override
  AbstractBool isNumber(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isNumber(value._powersetBits),
          _abstractValueDomain.isNumber(value._abstractValue));

  @override
  AbstractBool isIntegerOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isIntegerOrNull(value._powersetBits),
          _abstractValueDomain.isIntegerOrNull(value._abstractValue));

  @override
  AbstractBool isPositiveIntegerOrNull(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPositiveIntegerOrNull(value._powersetBits),
          _abstractValueDomain.isPositiveIntegerOrNull(value._abstractValue));

  @override
  AbstractBool isPositiveInteger(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPositiveInteger(value._powersetBits),
          _abstractValueDomain.isPositiveInteger(value._abstractValue));

  @override
  AbstractBool isUInt31(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isUInt31(value._powersetBits),
          _abstractValueDomain.isUInt31(value._abstractValue));

  @override
  AbstractBool isUInt32(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isUInt32(value._powersetBits),
          _abstractValueDomain.isUInt32(value._abstractValue));

  @override
  AbstractBool isInteger(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isInteger(value._powersetBits),
          _abstractValueDomain.isInteger(value._abstractValue));

  @override
  AbstractBool isInterceptor(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isInterceptor(value._powersetBits),
          _abstractValueDomain.isInterceptor(value._abstractValue));

  @override
  AbstractBool isPrimitiveString(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPrimitiveString(value._powersetBits),
          _abstractValueDomain.isPrimitiveString(value._abstractValue));

  @override
  AbstractBool isArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isArray(value._powersetBits),
          _abstractValueDomain.isArray(value._abstractValue));

  @override
  AbstractBool isMutableIndexable(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isMutableIndexable(value._powersetBits),
          _abstractValueDomain.isMutableIndexable(value._abstractValue));

  @override
  AbstractBool isMutableArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isMutableArray(value._powersetBits),
          _abstractValueDomain.isMutableArray(value._abstractValue));

  @override
  AbstractBool isExtendableArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isExtendableArray(value._powersetBits),
          _abstractValueDomain.isExtendableArray(value._abstractValue));

  @override
  AbstractBool isFixedArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isFixedArray(value._powersetBits),
          _abstractValueDomain.isFixedArray(value._abstractValue));

  @override
  AbstractBool isIndexablePrimitive(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isIndexablePrimitive(value._powersetBits),
          _abstractValueDomain.isIndexablePrimitive(value._abstractValue));

  @override
  AbstractBool isPrimitiveBoolean(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPrimitiveBoolean(value._powersetBits),
          _abstractValueDomain.isPrimitiveBoolean(value._abstractValue));

  @override
  AbstractBool isPrimitiveNumber(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPrimitiveNumber(value._powersetBits),
          _abstractValueDomain.isPrimitiveNumber(value._abstractValue));

  @override
  AbstractBool isPrimitive(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isPrimitive(value._powersetBits),
          _abstractValueDomain.isPrimitive(value._abstractValue));

  @override
  AbstractBool isNull(covariant PowersetValue value) => AbstractBool.strengthen(
      _powersetBitsDomain.isNull(value._powersetBits),
      _abstractValueDomain.isNull(value._abstractValue));

  @override
  AbstractBool isLateSentinel(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isLateSentinel(value._powersetBits),
          _abstractValueDomain.isLateSentinel(value._abstractValue));

  @override
  ClassEntity? getExactClass(covariant PowersetValue value) =>
      _abstractValueDomain.getExactClass(value._abstractValue);

  @override
  AbstractBool isExact(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isExact(value._powersetBits),
          _abstractValueDomain.isExact(value._abstractValue));

  @override
  AbstractBool isEmpty(covariant PowersetValue value) =>
      AbstractBool.strengthen(_powersetBitsDomain.isEmpty(value._powersetBits),
          _abstractValueDomain.isEmpty(value._abstractValue));

  @override
  AbstractBool isInstanceOf(covariant PowersetValue value, ClassEntity cls) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isInstanceOf(value._powersetBits, cls),
          _abstractValueDomain.isInstanceOf(value._abstractValue, cls));

  @override
  AbstractBool isInstanceOfOrNull(
          covariant PowersetValue value, ClassEntity cls) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isInstanceOfOrNull(value._powersetBits, cls),
          _abstractValueDomain.isInstanceOfOrNull(value._abstractValue, cls));

  @override
  AbstractBool containsOnlyType(
          covariant PowersetValue value, ClassEntity cls) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.containsOnlyType(value._powersetBits, cls),
          _abstractValueDomain.containsOnlyType(value._abstractValue, cls));

  @override
  AbstractBool containsType(covariant PowersetValue value, ClassEntity cls) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.containsType(value._powersetBits, cls),
          _abstractValueDomain.containsType(value._abstractValue, cls));

  @override
  AbstractValue includeNull(covariant PowersetValue value) {
    int powersetBits = _powersetBitsDomain.includeNull(value._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.includeNull(value._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue excludeNull(covariant PowersetValue value) {
    int powersetBits = _powersetBitsDomain.excludeNull(value._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.excludeNull(value._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue includeLateSentinel(covariant PowersetValue value) {
    int powersetBits =
        _powersetBitsDomain.includeLateSentinel(value._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.includeLateSentinel(value._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue excludeLateSentinel(covariant PowersetValue value) {
    int powersetBits =
        _powersetBitsDomain.excludeLateSentinel(value._powersetBits);
    AbstractValue abstractValue =
        _abstractValueDomain.excludeLateSentinel(value._abstractValue);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractBool couldBeTypedArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.couldBeTypedArray(value._powersetBits),
          _abstractValueDomain.couldBeTypedArray(value._abstractValue));

  @override
  AbstractBool isTypedArray(covariant PowersetValue value) =>
      AbstractBool.strengthen(
          _powersetBitsDomain.isTypedArray(value._powersetBits),
          _abstractValueDomain.isTypedArray(value._abstractValue));

  @override
  AbstractValue createNullableSubtype(ClassEntity cls) {
    int powersetBits = _powersetBitsDomain.createNullableSubtype(cls);
    AbstractValue abstractValue =
        _abstractValueDomain.createNullableSubtype(cls);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue createNonNullSubtype(ClassEntity cls) {
    int powersetBits = _powersetBitsDomain.createNonNullSubtype(cls);
    AbstractValue abstractValue =
        _abstractValueDomain.createNonNullSubtype(cls);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue createNonNullSubclass(ClassEntity cls) {
    int powersetBits = _powersetBitsDomain.createNonNullSubclass(cls);
    AbstractValue abstractValue =
        _abstractValueDomain.createNonNullSubclass(cls);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue createNullableExact(ClassEntity cls) {
    int powersetBits = _powersetBitsDomain.createNullableExact(cls);
    AbstractValue abstractValue = _abstractValueDomain.createNullableExact(cls);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValue createNonNullExact(ClassEntity cls) {
    int powersetBits = _powersetBitsDomain.createNonNullExact(cls);
    AbstractValue abstractValue = _abstractValueDomain.createNonNullExact(cls);
    return PowersetValue(abstractValue, powersetBits);
  }

  @override
  AbstractValueWithPrecision createFromStaticType(DartType type,
      {ClassRelation classRelation = ClassRelation.subtype,
      required bool nullable}) {
    int powersetBits = _powersetBitsDomain.createFromStaticType(type,
        classRelation: classRelation, nullable: nullable);
    var unwrapped = _abstractValueDomain.createFromStaticType(type,
        classRelation: classRelation, nullable: nullable);
    return AbstractValueWithPrecision(
        PowersetValue(unwrapped.abstractValue, powersetBits),
        unwrapped.isPrecise);
  }

  @override
  AbstractValue get asyncStarStreamType => PowersetValue(
      _abstractValueDomain.asyncStarStreamType,
      _powersetBitsDomain.asyncStarStreamType);

  @override
  AbstractValue get asyncFutureType => PowersetValue(
      _abstractValueDomain.asyncFutureType,
      _powersetBitsDomain.asyncFutureType);

  @override
  AbstractValue get syncStarIterableType => PowersetValue(
      _abstractValueDomain.syncStarIterableType,
      _powersetBitsDomain.syncStarIterableType);

  @override
  AbstractValue get emptyType => PowersetValue(
      _abstractValueDomain.emptyType, _powersetBitsDomain.emptyType);

  @override
  AbstractValue get constMapType => PowersetValue(
      _abstractValueDomain.constMapType, _powersetBitsDomain.constMapType);

  @override
  AbstractValue get constSetType => PowersetValue(
      _abstractValueDomain.constSetType, _powersetBitsDomain.constSetType);

  @override
  AbstractValue get constListType => PowersetValue(
      _abstractValueDomain.constListType, _powersetBitsDomain.constListType);

  @override
  AbstractValue get positiveIntType => PowersetValue(
      _abstractValueDomain.positiveIntType,
      _powersetBitsDomain.positiveIntType);

  @override
  AbstractValue get uint32Type => PowersetValue(
      _abstractValueDomain.uint32Type, _powersetBitsDomain.uint32Type);

  @override
  AbstractValue get uint31Type => PowersetValue(
      _abstractValueDomain.uint31Type, _powersetBitsDomain.uint31Type);

  @override
  AbstractValue get fixedListType => PowersetValue(
      _abstractValueDomain.fixedListType, _powersetBitsDomain.fixedListType);

  @override
  AbstractValue get growableListType => PowersetValue(
      _abstractValueDomain.growableListType,
      _powersetBitsDomain.growableListType);

  @override
  AbstractValue get mutableArrayType => PowersetValue(
      _abstractValueDomain.mutableArrayType,
      _powersetBitsDomain.mutableArrayType);

  @override
  AbstractValue get nullType => PowersetValue(
      _abstractValueDomain.nullType, _powersetBitsDomain.nullType);

  @override
  AbstractValue get nonNullType => PowersetValue(
      _abstractValueDomain.nonNullType, _powersetBitsDomain.nonNullType);

  @override
  AbstractValue get lateSentinelType => PowersetValue(
      _abstractValueDomain.lateSentinelType,
      _powersetBitsDomain.lateSentinelType);

  @override
  AbstractValue get mapType =>
      PowersetValue(_abstractValueDomain.mapType, _powersetBitsDomain.mapType);

  @override
  AbstractValue get setType =>
      PowersetValue(_abstractValueDomain.setType, _powersetBitsDomain.setType);

  @override
  AbstractValue get listType => PowersetValue(
      _abstractValueDomain.listType, _powersetBitsDomain.listType);

  @override
  AbstractValue get stringType => PowersetValue(
      _abstractValueDomain.stringType, _powersetBitsDomain.stringType);

  @override
  AbstractValue get numType =>
      PowersetValue(_abstractValueDomain.numType, _powersetBitsDomain.numType);

  @override
  AbstractValue get numNotIntType => PowersetValue(
      _abstractValueDomain.numNotIntType, _powersetBitsDomain.numNotIntType);

  @override
  AbstractValue get intType =>
      PowersetValue(_abstractValueDomain.intType, _powersetBitsDomain.intType);

  @override
  AbstractValue get boolType => PowersetValue(
      _abstractValueDomain.boolType, _powersetBitsDomain.boolType);

  @override
  AbstractValue get functionType => PowersetValue(
      _abstractValueDomain.functionType, _powersetBitsDomain.functionType);

  @override
  AbstractValue get recordType => PowersetValue(
      _abstractValueDomain.recordType, _powersetBitsDomain.recordType);

  @override
  AbstractValue get typeType => PowersetValue(
      _abstractValueDomain.typeType, _powersetBitsDomain.typeType);

  @override
  Iterable<DynamicCallTarget> findRootsOfTargets(
          covariant PowersetValue receiver,
          Selector selector,
          MemberHierarchyBuilder memberHierarchyBuilder) =>
      _abstractValueDomain.findRootsOfTargets(
          receiver.abstractValue, selector, memberHierarchyBuilder);
}

class PowersetStrategy implements AbstractValueStrategy {
  final AbstractValueStrategy _abstractValueStrategy;
  const PowersetStrategy(this._abstractValueStrategy);

  @override
  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
    return PowersetDomain(_abstractValueStrategy.createDomain(closedWorld),
        PowersetBitsDomain(closedWorld));
  }

  @override
  SelectorConstraintsStrategy createSelectorStrategy() {
    return PowersetsSelectorStrategy(
        _abstractValueStrategy.createSelectorStrategy());
  }
}

class PowersetsSelectorStrategy implements SelectorConstraintsStrategy {
  final SelectorConstraintsStrategy _selectorConstraintsStrategy;
  const PowersetsSelectorStrategy(this._selectorConstraintsStrategy);

  @override
  UniverseSelectorConstraints createSelectorConstraints(
      Selector selector, Object? initialConstraint) {
    return PowersetsUniverseSelectorConstraints(
        _selectorConstraintsStrategy.createSelectorConstraints(
            selector,
            initialConstraint == null
                ? null
                : (initialConstraint as PowersetValue)._abstractValue));
  }

  @override
  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
      covariant JClosedWorld world) {
    return _selectorConstraintsStrategy.appliedUnnamed(
        dynamicUse.withReceiverConstraint(
            unwrapOrNull(dynamicUse.receiverConstraint as PowersetValue?)),
        member,
        world);
  }
}

class PowersetsUniverseSelectorConstraints
    implements UniverseSelectorConstraints {
  final UniverseSelectorConstraints _universeSelectorConstraints;
  const PowersetsUniverseSelectorConstraints(this._universeSelectorConstraints);

  @override
  bool addReceiverConstraint(Object? constraint) =>
      _universeSelectorConstraints.addReceiverConstraint(constraint == null
          ? null
          : (constraint as PowersetValue)._abstractValue);

  @override
  bool needsNoSuchMethodHandling(Selector selector, World world) =>
      _universeSelectorConstraints.needsNoSuchMethodHandling(selector, world);

  @override
  bool canHit(MemberEntity element, Name name, World world) =>
      _universeSelectorConstraints.canHit(element, name, world);

  @override
  String toString() => 'PowersetsUniverseSelectorConstraints:$hashCode';
}
