| Index: sdk/lib/_internal/compiler/implementation/ssa/types.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/types.dart (revision 15379)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/types.dart (working copy)
|
| @@ -18,7 +18,7 @@
|
| if (identical(element.kind, ElementKind.TYPE_VARIABLE)) {
|
| // TODO(ngeoffray): Replace object type with [type].
|
| return new HBoundedPotentialPrimitiveType(
|
| - compiler.objectClass.computeType(compiler), canBeNull);
|
| + compiler.objectClass.computeType(compiler), canBeNull, true);
|
| }
|
|
|
| if (identical(element, compiler.intClass)) {
|
| @@ -38,6 +38,9 @@
|
| return new HBoundedPotentialPrimitiveNumberOrString(type, canBeNull);
|
| } else if (Elements.isStringOnlySupertype(element, compiler)) {
|
| return new HBoundedPotentialPrimitiveString(type, canBeNull);
|
| + } else if (identical(element, compiler.objectClass)) {
|
| + return new HBoundedPotentialPrimitiveType(
|
| + compiler.objectClass.computeType(compiler), canBeNull, true);
|
| } else {
|
| return canBeNull ? new HBoundedType.withNull(type)
|
| : new HBoundedType.nonNull(type);
|
| @@ -85,6 +88,7 @@
|
| bool isPrimitive() => false;
|
| bool isExact() => false;
|
| bool isPrimitiveOrNull() => false;
|
| + bool isTop() => false;
|
|
|
| bool canBePrimitive() => false;
|
| bool canBeNull() => false;
|
| @@ -218,6 +222,9 @@
|
| if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
|
| if (other.isBoolean()) return HType.BOOLEAN;
|
| if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
|
| + if (other.isTop()) {
|
| + return other.canBeNull() ? this : HType.BOOLEAN;
|
| + }
|
| if (other.canBeNull()) return HType.NULL;
|
| return HType.CONFLICTING;
|
| }
|
| @@ -278,6 +285,9 @@
|
| if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
|
| if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
|
| if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
|
| + if (other.isTop()) {
|
| + return other.canBeNull() ? this : HType.NUMBER;
|
| + }
|
| if (other.canBeNull()) return HType.NULL;
|
| return HType.CONFLICTING;
|
| }
|
| @@ -342,6 +352,9 @@
|
| if (other.isDoubleOrNull()) return HType.NULL;
|
| if (other.isNumber()) return HType.INTEGER;
|
| if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
|
| + if (other.isTop()) {
|
| + return other.canBeNull() ? this : HType.INTEGER;
|
| + }
|
| if (other.canBeNull()) return HType.NULL;
|
| return HType.CONFLICTING;
|
| }
|
| @@ -410,6 +423,9 @@
|
| if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
|
| if (other.isNumber()) return HType.DOUBLE;
|
| if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
|
| + if (other.isTop()) {
|
| + return other.canBeNull() ? this : HType.DOUBLE;
|
| + }
|
| if (other.canBeNull()) return HType.NULL;
|
| return HType.CONFLICTING;
|
| }
|
| @@ -525,6 +541,9 @@
|
| if (other is HBoundedPotentialPrimitiveString) {
|
| return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
|
| }
|
| + if (other.isTop()) {
|
| + return other.canBeNull() ? this : HType.STRING;
|
| + }
|
| if (other.canBeNull()) return HType.NULL;
|
| return HType.CONFLICTING;
|
| }
|
| @@ -679,8 +698,8 @@
|
| final bool _canBeNull;
|
| final bool _isExact;
|
|
|
| - toString() {
|
| - return 'BoundedType($type, $_canBeNull, $_isExact)';
|
| + String toString() {
|
| + return 'BoundedType($type, canBeNull: $_canBeNull, isExact: $_isExact)';
|
| }
|
|
|
| bool canBeNull() => _canBeNull;
|
| @@ -764,15 +783,47 @@
|
| }
|
|
|
| class HBoundedPotentialPrimitiveType extends HBoundedType {
|
| - const HBoundedPotentialPrimitiveType(DartType type, bool canBeNull)
|
| + final bool _isObject;
|
| + const HBoundedPotentialPrimitiveType(DartType type,
|
| + bool canBeNull,
|
| + this._isObject)
|
| : super(type, canBeNull, false);
|
| +
|
| + String toString() {
|
| + return 'BoundedPotentialPrimitiveType($type, canBeNull: $_canBeNull)';
|
| + }
|
| +
|
| bool canBePrimitive() => true;
|
| + bool isTop() => _isObject;
|
| +
|
| + HType union(HType other, Compiler compiler) {
|
| + if (isTop()) {
|
| + // The union of the top type and another type is the top type.
|
| + if (!canBeNull() && other.canBeNull()) {
|
| + return new HBoundedPotentialPrimitiveType(type, true, true);
|
| + } else {
|
| + return this;
|
| + }
|
| + } else {
|
| + return super.union(other, compiler);
|
| + }
|
| + }
|
| +
|
| + HType intersection(HType other, Compiler compiler) {
|
| + if (isTop()) {
|
| + // The intersection of the top type and any other type is the other type.
|
| + // TODO(ngeoffray): Also update the canBeNull information.
|
| + return other;
|
| + } else {
|
| + return super.intersection(other, compiler);
|
| + }
|
| + }
|
| }
|
|
|
| class HBoundedPotentialPrimitiveNumberOrString
|
| extends HBoundedPotentialPrimitiveType {
|
| const HBoundedPotentialPrimitiveNumberOrString(DartType type, bool canBeNull)
|
| - : super(type, canBeNull);
|
| + : super(type, canBeNull, false);
|
|
|
| HType union(HType other, Compiler compiler) {
|
| if (other.isNumber()) return this;
|
| @@ -812,7 +863,7 @@
|
|
|
| class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType {
|
| const HBoundedPotentialPrimitiveArray(DartType type, bool canBeNull)
|
| - : super(type, canBeNull);
|
| + : super(type, canBeNull, false);
|
|
|
| HType union(HType other, Compiler compiler) {
|
| if (other.isString()) return HType.UNKNOWN;
|
| @@ -840,7 +891,7 @@
|
|
|
| class HBoundedPotentialPrimitiveString extends HBoundedPotentialPrimitiveType {
|
| const HBoundedPotentialPrimitiveString(DartType type, bool canBeNull)
|
| - : super(type, canBeNull);
|
| + : super(type, canBeNull, false);
|
|
|
| bool isPrimitiveOrNull() => true;
|
|
|
|
|