mirror of
https://github.com/dart-lang/sdk
synced 2024-09-04 16:03:44 +00:00
[dart2js] Add abstract value domain to distinguish uncomputed values.
Normal dart2js invocations will continue using the existing abstract value domains with `emptyType` as the initial type for type graph nodes. When an appropriate debug flag is passed, all abstract values will be wrapped so that the underlying empty type is only used when a value is known to be empty. Abstract values which have not yet been computed will print as "[uncomputed]" in order to aid in debugging but will otherwise behave like the empty type during type graph construction. Change-Id: I1ec41e42e8b566a0a6bfe969c2ff96f4e53d5f4e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243844 Commit-Queue: Mayank Patke <fishythefish@google.com> Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
parent
053c633d0b
commit
278815b192
|
@ -38,8 +38,9 @@ import 'elements/entities.dart';
|
||||||
import 'enqueue.dart' show Enqueuer;
|
import 'enqueue.dart' show Enqueuer;
|
||||||
import 'environment.dart';
|
import 'environment.dart';
|
||||||
import 'inferrer/abstract_value_strategy.dart';
|
import 'inferrer/abstract_value_strategy.dart';
|
||||||
import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
|
import 'inferrer/computable.dart' show ComputableAbstractValueStrategy;
|
||||||
import 'inferrer/powersets/powersets.dart' show PowersetStrategy;
|
import 'inferrer/powersets/powersets.dart' show PowersetStrategy;
|
||||||
|
import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
|
||||||
import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
|
import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
|
||||||
import 'inferrer/types.dart'
|
import 'inferrer/types.dart'
|
||||||
show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
|
show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
|
||||||
|
@ -189,6 +190,10 @@ class Compiler
|
||||||
} else if (options.experimentalPowersets) {
|
} else if (options.experimentalPowersets) {
|
||||||
abstractValueStrategy = PowersetStrategy(abstractValueStrategy);
|
abstractValueStrategy = PowersetStrategy(abstractValueStrategy);
|
||||||
}
|
}
|
||||||
|
if (options.debugGlobalInference) {
|
||||||
|
abstractValueStrategy =
|
||||||
|
ComputableAbstractValueStrategy(abstractValueStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
CompilerTask kernelFrontEndTask;
|
CompilerTask kernelFrontEndTask;
|
||||||
selfTask = GenericTask('self', measurer);
|
selfTask = GenericTask('self', measurer);
|
||||||
|
|
|
@ -92,6 +92,12 @@ class AbstractValueWithPrecision {
|
||||||
|
|
||||||
/// A system that implements an abstraction over runtime values.
|
/// A system that implements an abstraction over runtime values.
|
||||||
abstract class AbstractValueDomain {
|
abstract class AbstractValueDomain {
|
||||||
|
/// The [AbstractValue] that represents a type which has not yet been
|
||||||
|
/// computed. Type graph nodes may carry this type during construction of the
|
||||||
|
/// graph, but it should be replaced by a computed type by the time the graph
|
||||||
|
/// is queried.
|
||||||
|
AbstractValue get uncomputedType => emptyType;
|
||||||
|
|
||||||
/// The [AbstractValue] that represents an unknown runtime value. This
|
/// The [AbstractValue] that represents an unknown runtime value. This
|
||||||
/// includes values internal to the implementation, such as late sentinels.
|
/// includes values internal to the implementation, such as late sentinels.
|
||||||
AbstractValue get internalTopType;
|
AbstractValue get internalTopType;
|
||||||
|
|
673
pkg/compiler/lib/src/inferrer/computable.dart
Normal file
673
pkg/compiler/lib/src/inferrer/computable.dart
Normal file
|
@ -0,0 +1,673 @@
|
||||||
|
// 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 '../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 '../serialization/serialization.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';
|
||||||
|
|
||||||
|
class ComputableAbstractValue implements AbstractValue {
|
||||||
|
final AbstractValue? _wrappedValue;
|
||||||
|
const ComputableAbstractValue(this._wrappedValue);
|
||||||
|
|
||||||
|
bool get isComputed => _wrappedValue != null;
|
||||||
|
bool get isUncomputed => _wrappedValue == null;
|
||||||
|
|
||||||
|
AbstractValue _unwrapOrThrow() => isUncomputed
|
||||||
|
? throw StateError("Uncomputed abstract value")
|
||||||
|
: _wrappedValue!;
|
||||||
|
|
||||||
|
AbstractValue _unwrapOrEmpty(AbstractValueDomain wrappedDomain) =>
|
||||||
|
isUncomputed ? wrappedDomain.emptyType : _wrappedValue!;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (other is ComputableAbstractValue) {
|
||||||
|
return _wrappedValue == other._wrappedValue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _wrappedValue.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
isUncomputed ? "[uncomputed]" : _wrappedValue!.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComputableAbstractValueDomain with AbstractValueDomain {
|
||||||
|
final AbstractValueDomain _wrappedDomain;
|
||||||
|
const ComputableAbstractValueDomain(this._wrappedDomain);
|
||||||
|
|
||||||
|
AbstractValue _unwrap(ComputableAbstractValue value) =>
|
||||||
|
value._unwrapOrEmpty(_wrappedDomain);
|
||||||
|
|
||||||
|
AbstractValue? _unwrapOrNull(ComputableAbstractValue? value) =>
|
||||||
|
value?._unwrapOrEmpty(_wrappedDomain);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get uncomputedType => const ComputableAbstractValue(null);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get internalTopType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.internalTopType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get dynamicType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.dynamicType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get typeType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.typeType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get functionType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.functionType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get boolType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.boolType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get intType => ComputableAbstractValue(_wrappedDomain.intType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get numNotIntType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.numNotIntType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get numType => ComputableAbstractValue(_wrappedDomain.numType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get stringType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.stringType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get listType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.listType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get setType => ComputableAbstractValue(_wrappedDomain.setType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get mapType => ComputableAbstractValue(_wrappedDomain.mapType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get nonNullType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.nonNullType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get nullType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.nullType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get lateSentinelType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.lateSentinelType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get growableListType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.growableListType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get fixedListType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.fixedListType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get mutableArrayType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.mutableArrayType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get uint31Type =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.uint31Type);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get uint32Type =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.uint32Type);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get positiveIntType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.positiveIntType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get constListType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.constListType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get constSetType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.constSetType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get constMapType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.constMapType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get emptyType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.emptyType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get syncStarIterableType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.syncStarIterableType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get asyncFutureType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.asyncFutureType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue get asyncStarStreamType =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.asyncStarStreamType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValueWithPrecision createFromStaticType(DartType type,
|
||||||
|
{ClassRelation classRelation = ClassRelation.subtype,
|
||||||
|
required bool nullable}) {
|
||||||
|
final unwrapped = _wrappedDomain.createFromStaticType(type,
|
||||||
|
classRelation: classRelation, nullable: nullable);
|
||||||
|
return AbstractValueWithPrecision(
|
||||||
|
ComputableAbstractValue(unwrapped.abstractValue), unwrapped.isPrecise);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createNonNullExact(ClassEntity cls) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createNonNullExact(cls));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createNullableExact(ClassEntity cls) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createNullableExact(cls));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createNonNullSubclass(ClassEntity cls) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createNonNullSubclass(cls));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createNonNullSubtype(ClassEntity cls) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createNonNullSubtype(cls));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createNullableSubtype(ClassEntity cls) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createNullableSubtype(cls));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isTypedArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isTypedArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool couldBeTypedArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.couldBeTypedArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue excludeNull(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.excludeNull(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue includeNull(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.includeNull(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue excludeLateSentinel(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.excludeLateSentinel(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue includeLateSentinel(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.includeLateSentinel(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool containsType(
|
||||||
|
covariant ComputableAbstractValue value, ClassEntity cls) =>
|
||||||
|
_wrappedDomain.containsType(_unwrap(value), cls);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool containsOnlyType(
|
||||||
|
covariant ComputableAbstractValue value, ClassEntity cls) =>
|
||||||
|
_wrappedDomain.containsOnlyType(_unwrap(value), cls);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isInstanceOfOrNull(
|
||||||
|
covariant ComputableAbstractValue value, ClassEntity cls) =>
|
||||||
|
_wrappedDomain.isInstanceOfOrNull(_unwrap(value), cls);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isInstanceOf(
|
||||||
|
covariant ComputableAbstractValue value, ClassEntity cls) =>
|
||||||
|
_wrappedDomain.isInstanceOf(_unwrap(value), cls);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isEmpty(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isEmpty(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isExact(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isExact(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
ClassEntity? getExactClass(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getExactClass(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isLateSentinel(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isLateSentinel(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPrimitive(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitive(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPrimitiveNumber(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitiveNumber(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPrimitiveBoolean(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitiveBoolean(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isIndexablePrimitive(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isIndexablePrimitive(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isFixedArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isFixedArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isExtendableArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isExtendableArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isMutableArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isMutableArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isMutableIndexable(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isMutableIndexable(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isArray(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isArray(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPrimitiveString(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitiveString(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isInterceptor(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isInterceptor(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isInteger(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isInteger(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isUInt32(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isUInt32(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isUInt31(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isUInt31(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPositiveInteger(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPositiveInteger(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPositiveIntegerOrNull(
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPositiveIntegerOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isIntegerOrNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isIntegerOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isNumber(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isNumber(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isNumberOrNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isNumberOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isBoolean(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isBoolean(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isBooleanOrNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isBooleanOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isString(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isString(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isStringOrNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isStringOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isPrimitiveOrNull(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitiveOrNull(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isTruthy(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isTruthy(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue union(covariant ComputableAbstractValue a,
|
||||||
|
covariant ComputableAbstractValue b) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.union(_unwrap(a), _unwrap(b)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.unionOfMany(values.map(
|
||||||
|
(AbstractValue value) => _unwrap(value as ComputableAbstractValue))));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue intersection(covariant ComputableAbstractValue a,
|
||||||
|
covariant ComputableAbstractValue b) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.intersection(_unwrap(a), _unwrap(b)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool areDisjoint(covariant ComputableAbstractValue a,
|
||||||
|
covariant ComputableAbstractValue b) =>
|
||||||
|
_wrappedDomain.areDisjoint(_unwrap(a), _unwrap(b));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool containsAll(covariant ComputableAbstractValue a) =>
|
||||||
|
_wrappedDomain.containsAll(_unwrap(a));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue computeAbstractValueForConstant(
|
||||||
|
covariant ConstantValue value) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.computeAbstractValueForConstant(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isContainer(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isContainer(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createContainerValue(
|
||||||
|
covariant ComputableAbstractValue? originalValue,
|
||||||
|
Object? allocationNode,
|
||||||
|
MemberEntity? allocationElement,
|
||||||
|
covariant ComputableAbstractValue elementType,
|
||||||
|
int? length) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createContainerValue(
|
||||||
|
_unwrapOrNull(originalValue),
|
||||||
|
allocationNode,
|
||||||
|
allocationElement,
|
||||||
|
_unwrap(elementType),
|
||||||
|
length));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue getContainerElementType(
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.getContainerElementType(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
int? getContainerLength(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getContainerLength(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isSet(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isSet(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createSetValue(
|
||||||
|
covariant ComputableAbstractValue? originalValue,
|
||||||
|
Object? allocationNode,
|
||||||
|
MemberEntity? allocationElement,
|
||||||
|
covariant ComputableAbstractValue elementType) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createSetValue(
|
||||||
|
_unwrapOrNull(originalValue),
|
||||||
|
allocationNode,
|
||||||
|
allocationElement,
|
||||||
|
_unwrap(elementType)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue getSetElementType(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.getSetElementType(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isMap(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isMap(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createMapValue(
|
||||||
|
covariant ComputableAbstractValue? originalValue,
|
||||||
|
Object? allocationNode,
|
||||||
|
MemberEntity? allocationElement,
|
||||||
|
covariant ComputableAbstractValue key,
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createMapValue(
|
||||||
|
_unwrapOrNull(originalValue),
|
||||||
|
allocationNode,
|
||||||
|
allocationElement,
|
||||||
|
_unwrap(key),
|
||||||
|
_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue getMapKeyType(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.getMapKeyType(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue getMapValueType(covariant ComputableAbstractValue value) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.getMapValueType(_unwrap(value)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isDictionary(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isDictionary(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createDictionaryValue(
|
||||||
|
covariant ComputableAbstractValue? originalValue,
|
||||||
|
Object? allocationNode,
|
||||||
|
MemberEntity? allocationElement,
|
||||||
|
covariant ComputableAbstractValue key,
|
||||||
|
covariant ComputableAbstractValue value,
|
||||||
|
covariant Map<String, AbstractValue> mappings) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.createDictionaryValue(
|
||||||
|
_unwrapOrNull(originalValue),
|
||||||
|
allocationNode,
|
||||||
|
allocationElement,
|
||||||
|
_unwrap(key),
|
||||||
|
_unwrap(value), {
|
||||||
|
for (final entry in mappings.entries)
|
||||||
|
entry.key: _unwrap(entry.value as ComputableAbstractValue)
|
||||||
|
}));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool containsDictionaryKey(
|
||||||
|
covariant ComputableAbstractValue value, String key) =>
|
||||||
|
value.isComputed &&
|
||||||
|
_wrappedDomain.containsDictionaryKey(value._wrappedValue!, key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue getDictionaryValueForKey(
|
||||||
|
covariant ComputableAbstractValue value, String key) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.getDictionaryValueForKey(_unwrap(value), key));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isSpecializationOf(covariant ComputableAbstractValue specialization,
|
||||||
|
covariant ComputableAbstractValue generalization) =>
|
||||||
|
_wrappedDomain.isSpecializationOf(
|
||||||
|
_unwrap(specialization), _unwrap(generalization));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue? getGeneralization(covariant ComputableAbstractValue? value) {
|
||||||
|
final generalization =
|
||||||
|
_wrappedDomain.getGeneralization(_unwrapOrNull(value));
|
||||||
|
if (generalization == null) return null;
|
||||||
|
return ComputableAbstractValue(generalization);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object? getAllocationNode(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getAllocationNode(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
MemberEntity? getAllocationElement(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getAllocationElement(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isPrimitiveValue(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isPrimitiveValue(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue createPrimitiveValue(
|
||||||
|
covariant ComputableAbstractValue originalValue,
|
||||||
|
PrimitiveConstantValue value) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.createPrimitiveValue(_unwrap(originalValue), value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
PrimitiveConstantValue? getPrimitiveValue(
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getPrimitiveValue(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue computeReceiver(Iterable<MemberEntity> members) =>
|
||||||
|
ComputableAbstractValue(_wrappedDomain.computeReceiver(members));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isTargetingMember(covariant ComputableAbstractValue receiver,
|
||||||
|
MemberEntity member, Name name) =>
|
||||||
|
_wrappedDomain.isTargetingMember(_unwrap(receiver), member, name);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool needsNoSuchMethodHandling(
|
||||||
|
covariant ComputableAbstractValue receiver, Selector selector) =>
|
||||||
|
_wrappedDomain.needsNoSuchMethodHandling(_unwrap(receiver), selector);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
|
||||||
|
final value =
|
||||||
|
_wrappedDomain.getAbstractValueForNativeMethodParameterType(type);
|
||||||
|
if (value == null) return null;
|
||||||
|
return ComputableAbstractValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isIn(covariant ComputableAbstractValue subset,
|
||||||
|
covariant ComputableAbstractValue superset) =>
|
||||||
|
_wrappedDomain.isIn(_unwrap(subset), _unwrap(superset));
|
||||||
|
|
||||||
|
@override
|
||||||
|
MemberEntity? locateSingleMember(
|
||||||
|
covariant ComputableAbstractValue receiver, Selector selector) =>
|
||||||
|
_wrappedDomain.locateSingleMember(_unwrap(receiver), selector);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isJsIndexable(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isJsIndexable(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isJsIndexableAndIterable(
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isJsIndexableAndIterable(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractBool isFixedLengthJsIndexable(
|
||||||
|
covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.isFixedLengthJsIndexable(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getCompactText(covariant ComputableAbstractValue value) =>
|
||||||
|
_wrappedDomain.getCompactText(_unwrap(value));
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValue readAbstractValueFromDataSource(DataSourceReader source) =>
|
||||||
|
ComputableAbstractValue(
|
||||||
|
_wrappedDomain.readAbstractValueFromDataSource(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeAbstractValueToDataSink(
|
||||||
|
DataSinkWriter sink, covariant ComputableAbstractValue value) {
|
||||||
|
_wrappedDomain.writeAbstractValueToDataSink(sink, _unwrap(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComputableAbstractValueStrategy implements AbstractValueStrategy {
|
||||||
|
final AbstractValueStrategy _wrappedStrategy;
|
||||||
|
|
||||||
|
const ComputableAbstractValueStrategy(this._wrappedStrategy);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AbstractValueDomain createDomain(JClosedWorld closedWorld) =>
|
||||||
|
ComputableAbstractValueDomain(_wrappedStrategy.createDomain(closedWorld));
|
||||||
|
|
||||||
|
@override
|
||||||
|
SelectorConstraintsStrategy createSelectorStrategy() =>
|
||||||
|
ComputableSelectorStrategy(_wrappedStrategy.createSelectorStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComputableSelectorStrategy implements SelectorConstraintsStrategy {
|
||||||
|
final SelectorConstraintsStrategy _wrappedStrategy;
|
||||||
|
|
||||||
|
const ComputableSelectorStrategy(this._wrappedStrategy);
|
||||||
|
|
||||||
|
// There should be no uncomputed values at this point, so throw instead of
|
||||||
|
// requiring a domain.
|
||||||
|
AbstractValue? _unwrap(ComputableAbstractValue? value) =>
|
||||||
|
value?._unwrapOrThrow();
|
||||||
|
|
||||||
|
@override
|
||||||
|
UniverseSelectorConstraints createSelectorConstraints(
|
||||||
|
Selector selector, Object? initialConstraint) =>
|
||||||
|
ComputableUniverseSelectorConstraints(
|
||||||
|
_wrappedStrategy.createSelectorConstraints(
|
||||||
|
selector, _unwrap(initialConstraint as ComputableAbstractValue)));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
|
||||||
|
covariant JClosedWorld world) =>
|
||||||
|
_wrappedStrategy.appliedUnnamed(
|
||||||
|
dynamicUse.withReceiverConstraint(_unwrap(
|
||||||
|
dynamicUse.receiverConstraint as ComputableAbstractValue)),
|
||||||
|
member,
|
||||||
|
world);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComputableUniverseSelectorConstraints
|
||||||
|
implements UniverseSelectorConstraints {
|
||||||
|
final UniverseSelectorConstraints _universeSelectorConstraints;
|
||||||
|
|
||||||
|
const ComputableUniverseSelectorConstraints(
|
||||||
|
this._universeSelectorConstraints);
|
||||||
|
|
||||||
|
// There should be no uncomputed values at this point, so throw instead of
|
||||||
|
// requiring a domain.
|
||||||
|
AbstractValue? _unwrap(ComputableAbstractValue? value) =>
|
||||||
|
value?._unwrapOrThrow();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool addReceiverConstraint(covariant ComputableAbstractValue constraint) =>
|
||||||
|
_universeSelectorConstraints.addReceiverConstraint(_unwrap(constraint));
|
||||||
|
|
||||||
|
@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() => 'ComputableUniverseSelectorConstraints:$hashCode';
|
||||||
|
}
|
|
@ -53,7 +53,7 @@ PowersetValue? wrapOrNull(AbstractValue? abstractValue, int powersetBits) {
|
||||||
: PowersetValue(abstractValue, powersetBits);
|
: PowersetValue(abstractValue, powersetBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PowersetDomain implements AbstractValueDomain {
|
class PowersetDomain with AbstractValueDomain {
|
||||||
final AbstractValueDomain _abstractValueDomain;
|
final AbstractValueDomain _abstractValueDomain;
|
||||||
final PowersetBitsDomain _powersetBitsDomain;
|
final PowersetBitsDomain _powersetBitsDomain;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TrivialAbstractValue implements AbstractValue {
|
||||||
String toString() => '?';
|
String toString() => '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrivialAbstractValueDomain implements AbstractValueDomain {
|
class TrivialAbstractValueDomain with AbstractValueDomain {
|
||||||
const TrivialAbstractValueDomain();
|
const TrivialAbstractValueDomain();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -177,7 +177,7 @@ abstract class TypeInformation {
|
||||||
|
|
||||||
bool reset(InferrerEngine inferrer) {
|
bool reset(InferrerEngine inferrer) {
|
||||||
if (abandonInferencing) return false;
|
if (abandonInferencing) return false;
|
||||||
type = inferrer.abstractValueDomain.emptyType;
|
type = inferrer.abstractValueDomain.uncomputedType;
|
||||||
refineCount = 0;
|
refineCount = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ abstract class ApplyableTypeInformation implements TypeInformation {
|
||||||
class PlaceholderTypeInformation extends TypeInformation {
|
class PlaceholderTypeInformation extends TypeInformation {
|
||||||
PlaceholderTypeInformation(
|
PlaceholderTypeInformation(
|
||||||
AbstractValueDomain abstractValueDomain, MemberTypeInformation context)
|
AbstractValueDomain abstractValueDomain, MemberTypeInformation context)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void accept(TypeInformationVisitor visitor) {
|
void accept(TypeInformationVisitor visitor) {
|
||||||
|
@ -380,10 +380,11 @@ abstract class ElementTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
ElementTypeInformation._internal(
|
ElementTypeInformation._internal(
|
||||||
AbstractValueDomain abstractValueDomain, MemberTypeInformation? context)
|
AbstractValueDomain abstractValueDomain, MemberTypeInformation? context)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
ElementTypeInformation._withInputs(AbstractValueDomain abstractValueDomain,
|
ElementTypeInformation._withInputs(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, ParameterInputs inputs)
|
MemberTypeInformation? context, ParameterInputs inputs)
|
||||||
: super.withInputs(abstractValueDomain.emptyType, context, inputs);
|
: super.withInputs(abstractValueDomain.uncomputedType, context, inputs);
|
||||||
|
|
||||||
String getInferredSignature(TypeSystem types);
|
String getInferredSignature(TypeSystem types);
|
||||||
|
|
||||||
|
@ -967,9 +968,8 @@ abstract class CallSiteTypeInformation extends TypeInformation
|
||||||
this.selector,
|
this.selector,
|
||||||
this.arguments,
|
this.arguments,
|
||||||
this.inLoop)
|
this.inLoop)
|
||||||
: super.noInputs(abstractValueDomain.emptyType, context) {
|
: assert(_call is ir.Node || (_call == null && selector?.name == '==')),
|
||||||
assert(_call is ir.Node || (_call == null && selector?.name == '=='));
|
super.noInputs(abstractValueDomain.uncomputedType, context);
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'Call site $debugName $type';
|
String toString() => 'Call site $debugName $type';
|
||||||
|
@ -1603,7 +1603,7 @@ class NarrowTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
NarrowTypeInformation(AbstractValueDomain abstractValueDomain,
|
NarrowTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
TypeInformation narrowedType, this.typeAnnotation)
|
TypeInformation narrowedType, this.typeAnnotation)
|
||||||
: super(abstractValueDomain.emptyType, narrowedType.context) {
|
: super(abstractValueDomain.uncomputedType, narrowedType.context) {
|
||||||
addInput(narrowedType);
|
addInput(narrowedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1643,7 +1643,7 @@ abstract class InferredTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
InferredTypeInformation(AbstractValueDomain abstractValueDomain,
|
InferredTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, TypeInformation? parentType)
|
MemberTypeInformation? context, TypeInformation? parentType)
|
||||||
: super(abstractValueDomain.emptyType, context) {
|
: super(abstractValueDomain.uncomputedType, context) {
|
||||||
if (parentType != null) addInput(parentType);
|
if (parentType != null) addInput(parentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2025,7 +2025,7 @@ class PhiElementTypeInformation extends TypeInformation {
|
||||||
PhiElementTypeInformation(AbstractValueDomain abstractValueDomain,
|
PhiElementTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, this.branchNode, this.variable,
|
MemberTypeInformation? context, this.branchNode, this.variable,
|
||||||
{required this.isTry})
|
{required this.isTry})
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AbstractValue computeType(InferrerEngine inferrer) {
|
AbstractValue computeType(InferrerEngine inferrer) {
|
||||||
|
@ -2062,7 +2062,7 @@ class ClosureTypeInformation extends TypeInformation
|
||||||
|
|
||||||
ClosureTypeInformation(AbstractValueDomain abstractValueDomain,
|
ClosureTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, this._element)
|
MemberTypeInformation? context, this._element)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
FunctionEntity get closure => _element;
|
FunctionEntity get closure => _element;
|
||||||
|
|
||||||
|
@ -2126,7 +2126,7 @@ class AwaitTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
AwaitTypeInformation(AbstractValueDomain abstractValueDomain,
|
AwaitTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation context, this._node)
|
MemberTypeInformation context, this._node)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
// TODO(22894): Compute a better type here.
|
// TODO(22894): Compute a better type here.
|
||||||
@override
|
@override
|
||||||
|
@ -2148,7 +2148,7 @@ class YieldTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
YieldTypeInformation(AbstractValueDomain abstractValueDomain,
|
YieldTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation context, this._node)
|
MemberTypeInformation context, this._node)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
|
AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
|
||||||
|
|
|
@ -35,7 +35,7 @@ part 'type_mask.dart';
|
||||||
part 'union_type_mask.dart';
|
part 'union_type_mask.dart';
|
||||||
part 'value_type_mask.dart';
|
part 'value_type_mask.dart';
|
||||||
|
|
||||||
class CommonMasks implements AbstractValueDomain {
|
class CommonMasks with AbstractValueDomain {
|
||||||
// TODO(sigmund): once we split out the backend common elements, depend
|
// TODO(sigmund): once we split out the backend common elements, depend
|
||||||
// directly on those instead.
|
// directly on those instead.
|
||||||
final JClosedWorld _closedWorld;
|
final JClosedWorld _closedWorld;
|
||||||
|
|
|
@ -43,7 +43,7 @@ WrappedAbstractValue? wrapOrNull(AbstractValue? abstractValue) {
|
||||||
return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
|
return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrappedAbstractValueDomain implements AbstractValueDomain {
|
class WrappedAbstractValueDomain with AbstractValueDomain {
|
||||||
final AbstractValueDomain _abstractValueDomain;
|
final AbstractValueDomain _abstractValueDomain;
|
||||||
const WrappedAbstractValueDomain(this._abstractValueDomain);
|
const WrappedAbstractValueDomain(this._abstractValueDomain);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ PowersetValue? wrapOrNull(AbstractValue? abstractValue, int powersetBits) {
|
||||||
: PowersetValue(abstractValue, powersetBits);
|
: PowersetValue(abstractValue, powersetBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PowersetDomain implements AbstractValueDomain {
|
class PowersetDomain with AbstractValueDomain {
|
||||||
final AbstractValueDomain _abstractValueDomain;
|
final AbstractValueDomain _abstractValueDomain;
|
||||||
final PowersetBitsDomain _powersetBitsDomain;
|
final PowersetBitsDomain _powersetBitsDomain;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TrivialAbstractValue implements AbstractValue {
|
||||||
String toString() => '?';
|
String toString() => '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrivialAbstractValueDomain implements AbstractValueDomain {
|
class TrivialAbstractValueDomain with AbstractValueDomain {
|
||||||
const TrivialAbstractValueDomain();
|
const TrivialAbstractValueDomain();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -177,7 +177,7 @@ abstract class TypeInformation {
|
||||||
|
|
||||||
bool reset(InferrerEngine inferrer) {
|
bool reset(InferrerEngine inferrer) {
|
||||||
if (abandonInferencing) return false;
|
if (abandonInferencing) return false;
|
||||||
type = inferrer.abstractValueDomain.emptyType;
|
type = inferrer.abstractValueDomain.uncomputedType;
|
||||||
refineCount = 0;
|
refineCount = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ abstract class ApplyableTypeInformation implements TypeInformation {
|
||||||
class PlaceholderTypeInformation extends TypeInformation {
|
class PlaceholderTypeInformation extends TypeInformation {
|
||||||
PlaceholderTypeInformation(
|
PlaceholderTypeInformation(
|
||||||
AbstractValueDomain abstractValueDomain, MemberTypeInformation context)
|
AbstractValueDomain abstractValueDomain, MemberTypeInformation context)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void accept(TypeInformationVisitor visitor) {
|
void accept(TypeInformationVisitor visitor) {
|
||||||
|
@ -380,10 +380,11 @@ abstract class ElementTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
ElementTypeInformation._internal(
|
ElementTypeInformation._internal(
|
||||||
AbstractValueDomain abstractValueDomain, MemberTypeInformation? context)
|
AbstractValueDomain abstractValueDomain, MemberTypeInformation? context)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
ElementTypeInformation._withInputs(AbstractValueDomain abstractValueDomain,
|
ElementTypeInformation._withInputs(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, ParameterInputs inputs)
|
MemberTypeInformation? context, ParameterInputs inputs)
|
||||||
: super.withInputs(abstractValueDomain.emptyType, context, inputs);
|
: super.withInputs(abstractValueDomain.uncomputedType, context, inputs);
|
||||||
|
|
||||||
String getInferredSignature(TypeSystem types);
|
String getInferredSignature(TypeSystem types);
|
||||||
|
|
||||||
|
@ -967,9 +968,8 @@ abstract class CallSiteTypeInformation extends TypeInformation
|
||||||
this.selector,
|
this.selector,
|
||||||
this.arguments,
|
this.arguments,
|
||||||
this.inLoop)
|
this.inLoop)
|
||||||
: super.noInputs(abstractValueDomain.emptyType, context) {
|
: assert(_call is ir.Node || (_call == null && selector?.name == '==')),
|
||||||
assert(_call is ir.Node || (_call == null && selector?.name == '=='));
|
super.noInputs(abstractValueDomain.uncomputedType, context);
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'Call site $debugName $type';
|
String toString() => 'Call site $debugName $type';
|
||||||
|
@ -1596,7 +1596,7 @@ class NarrowTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
NarrowTypeInformation(AbstractValueDomain abstractValueDomain,
|
NarrowTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
TypeInformation narrowedType, this.typeAnnotation)
|
TypeInformation narrowedType, this.typeAnnotation)
|
||||||
: super(abstractValueDomain.emptyType, narrowedType.context) {
|
: super(abstractValueDomain.uncomputedType, narrowedType.context) {
|
||||||
addInput(narrowedType);
|
addInput(narrowedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1636,7 +1636,7 @@ abstract class InferredTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
InferredTypeInformation(AbstractValueDomain abstractValueDomain,
|
InferredTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, TypeInformation? parentType)
|
MemberTypeInformation? context, TypeInformation? parentType)
|
||||||
: super(abstractValueDomain.emptyType, context) {
|
: super(abstractValueDomain.uncomputedType, context) {
|
||||||
if (parentType != null) addInput(parentType);
|
if (parentType != null) addInput(parentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2018,7 +2018,7 @@ class PhiElementTypeInformation extends TypeInformation {
|
||||||
PhiElementTypeInformation(AbstractValueDomain abstractValueDomain,
|
PhiElementTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, this.branchNode, this.variable,
|
MemberTypeInformation? context, this.branchNode, this.variable,
|
||||||
{required this.isTry})
|
{required this.isTry})
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AbstractValue computeType(InferrerEngine inferrer) {
|
AbstractValue computeType(InferrerEngine inferrer) {
|
||||||
|
@ -2055,7 +2055,7 @@ class ClosureTypeInformation extends TypeInformation
|
||||||
|
|
||||||
ClosureTypeInformation(AbstractValueDomain abstractValueDomain,
|
ClosureTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation? context, this._element)
|
MemberTypeInformation? context, this._element)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
FunctionEntity get closure => _element;
|
FunctionEntity get closure => _element;
|
||||||
|
|
||||||
|
@ -2119,7 +2119,7 @@ class AwaitTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
AwaitTypeInformation(AbstractValueDomain abstractValueDomain,
|
AwaitTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation context, this._node)
|
MemberTypeInformation context, this._node)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
// TODO(22894): Compute a better type here.
|
// TODO(22894): Compute a better type here.
|
||||||
@override
|
@override
|
||||||
|
@ -2141,7 +2141,7 @@ class YieldTypeInformation extends TypeInformation {
|
||||||
|
|
||||||
YieldTypeInformation(AbstractValueDomain abstractValueDomain,
|
YieldTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
MemberTypeInformation context, this._node)
|
MemberTypeInformation context, this._node)
|
||||||
: super(abstractValueDomain.emptyType, context);
|
: super(abstractValueDomain.uncomputedType, context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
|
AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
|
||||||
|
|
|
@ -35,7 +35,7 @@ part 'type_mask.dart';
|
||||||
part 'union_type_mask.dart';
|
part 'union_type_mask.dart';
|
||||||
part 'value_type_mask.dart';
|
part 'value_type_mask.dart';
|
||||||
|
|
||||||
class CommonMasks implements AbstractValueDomain {
|
class CommonMasks with AbstractValueDomain {
|
||||||
// TODO(sigmund): once we split out the backend common elements, depend
|
// TODO(sigmund): once we split out the backend common elements, depend
|
||||||
// directly on those instead.
|
// directly on those instead.
|
||||||
final JClosedWorld _closedWorld;
|
final JClosedWorld _closedWorld;
|
||||||
|
|
|
@ -43,7 +43,7 @@ WrappedAbstractValue? wrapOrNull(AbstractValue? abstractValue) {
|
||||||
return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
|
return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrappedAbstractValueDomain implements AbstractValueDomain {
|
class WrappedAbstractValueDomain with AbstractValueDomain {
|
||||||
final AbstractValueDomain _abstractValueDomain;
|
final AbstractValueDomain _abstractValueDomain;
|
||||||
const WrappedAbstractValueDomain(this._abstractValueDomain);
|
const WrappedAbstractValueDomain(this._abstractValueDomain);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue