| // 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 '../../js_model/js_world.dart'; |
| import '../../serialization/serialization.dart'; |
| import '../../universe/member_hierarchy.dart'; |
| import '../../universe/record_shape.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 createRecordValue( |
| RecordShape shape, |
| List<AbstractValue> types, |
| ) { |
| AbstractValue abstractValue = _abstractValueDomain.createRecordValue( |
| shape, |
| types |
| .map((e) => (e as PowersetValue)._abstractValue) |
| .toList(growable: false), |
| ); |
| return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop); |
| } |
| |
| @override |
| bool isRecord(covariant PowersetValue value) => |
| _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue && |
| _abstractValueDomain.isRecord(value._abstractValue); |
| |
| @override |
| bool recordHasGetter(covariant PowersetValue value, String getterName) => |
| _abstractValueDomain.recordHasGetter(value._abstractValue, getterName); |
| |
| @override |
| AbstractValue getGetterTypeInRecord( |
| covariant PowersetValue value, |
| String getterName, |
| ) => _abstractValueDomain.getGetterTypeInRecord( |
| value._abstractValue, |
| getterName, |
| ); |
| |
| @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 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) { |
| int powersetBits = _powersetBitsDomain.createFromStaticType(type); |
| var unwrapped = _abstractValueDomain.createFromStaticType(type); |
| 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, |
| ); |
| |
| @override |
| bool isInvalidRefinement( |
| covariant PowersetValue before, |
| covariant PowersetValue after, |
| ) { |
| return _abstractValueDomain.isInvalidRefinement( |
| before._abstractValue, |
| after._abstractValue, |
| ); |
| } |
| } |
| |
| class PowersetStrategy implements AbstractValueStrategy<PowersetDomain> { |
| final AbstractValueStrategy _abstractValueStrategy; |
| const PowersetStrategy(this._abstractValueStrategy); |
| |
| @override |
| PowersetDomain createDomain(JClosedWorld closedWorld) { |
| return PowersetDomain( |
| _abstractValueStrategy.createDomain(closedWorld), |
| PowersetBitsDomain(closedWorld), |
| ); |
| } |
| |
| @override |
| SelectorConstraintsStrategy createSelectorStrategy(PowersetDomain domain) { |
| return PowersetsSelectorStrategy( |
| _abstractValueStrategy.createSelectorStrategy( |
| domain._abstractValueDomain, |
| ), |
| ); |
| } |
| } |
| |
| 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'; |
| } |