Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
index 87f9abeb58e426b238675eff6af539112b913ace..d8892fd01f24a1015571258cf8446673655001eb 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -28,15 +28,20 @@ abstract class TypeSystem<T> { |
T get stringType; |
T get listType; |
T get mapType; |
+ T get nonNullType; |
T getReturnType(FunctionElement element); |
T getSelectorReturnType(Selector selector); |
T getParameterType(ParameterElement element); |
+ T getFieldType(FieldElement element); |
T join(T a, T b); |
T typeOf(ConstantValue constant); |
+ T exact(ClassElement element); |
/// True if all values satisfying [type] are booleans (null is not a boolean). |
bool isDefinitelyBool(T type); |
+ |
+ bool isDefinitelyNotNull(T type); |
} |
class UnitTypeSystem implements TypeSystem<String> { |
@@ -50,14 +55,19 @@ class UnitTypeSystem implements TypeSystem<String> { |
get mapType => UNIT; |
get stringType => UNIT; |
get typeType => UNIT; |
+ get nonNullType => UNIT; |
getParameterType(_) => UNIT; |
getReturnType(_) => UNIT; |
getSelectorReturnType(_) => UNIT; |
+ getFieldType(_) => UNIT; |
join(a, b) => UNIT; |
typeOf(_) => UNIT; |
+ exact(_) => UNIT; |
bool isDefinitelyBool(_) => false; |
+ |
+ bool isDefinitelyNotNull(_) => false; |
} |
class TypeMaskSystem implements TypeSystem<TypeMask> { |
@@ -72,6 +82,7 @@ class TypeMaskSystem implements TypeSystem<TypeMask> { |
TypeMask get stringType => inferrer.stringType; |
TypeMask get listType => inferrer.listType; |
TypeMask get mapType => inferrer.mapType; |
+ TypeMask get nonNullType => inferrer.nonNullType; |
// TODO(karlklose): remove compiler here. |
TypeMaskSystem(dart2js.Compiler compiler) |
@@ -90,6 +101,10 @@ class TypeMaskSystem implements TypeSystem<TypeMask> { |
return inferrer.getGuaranteedTypeOfSelector(selector); |
} |
+ TypeMask getFieldType(FieldElement field) { |
+ return inferrer.getGuaranteedTypeOfElement(field); |
+ } |
+ |
@override |
TypeMask join(TypeMask a, TypeMask b) { |
return a.union(b, classWorld); |
@@ -100,9 +115,19 @@ class TypeMaskSystem implements TypeSystem<TypeMask> { |
return computeTypeMask(inferrer.compiler, constant); |
} |
+ TypeMask exact(ClassElement element) { |
+ // The class world does not know about classes created by |
+ // closure conversion, so just treat those as a subtypes of Function. |
+ // TODO(asgerf): Maybe closure conversion should create a new ClassWorld? |
+ if (element.isClosure) return functionType; |
karlklose
2015/06/02 12:53:22
We could also create ForwardingTypeMasks that unde
|
+ return new TypeMask.exact(element, classWorld); |
+ } |
+ |
bool isDefinitelyBool(TypeMask t) { |
return t.containsOnlyBool(classWorld) && !t.isNullable; |
} |
+ |
+ bool isDefinitelyNotNull(TypeMask t) => !t.isNullable; |
} |
/** |
@@ -274,6 +299,8 @@ class _TransformingVisitor<T> extends RecursiveVisitor { |
}); |
if (letPrim == null) { |
+ _AbstractValue<T> receiver = getValue(node.receiver.definition); |
+ node.receiverIsNotNull = receiver.isDefinitelyNotNull(typeSystem); |
super.visitInvokeMethod(node); |
} else { |
visitLetPrim(letPrim); |
@@ -453,7 +480,8 @@ class _TypePropagationVisitor<T> implements Visitor { |
void visitFunctionDefinition(FunctionDefinition node) { |
if (node.thisParameter != null) { |
- setValue(node.thisParameter, nonConstant()); |
+ // TODO(asgerf): Use a more precise type for 'this'. |
+ setValue(node.thisParameter, nonConstant(typeSystem.nonNullType)); |
} |
node.parameters.forEach(visit); |
setReachable(node.body); |
@@ -596,7 +624,7 @@ class _TypePropagationVisitor<T> implements Visitor { |
assert(cont.parameters.length == 1); |
Parameter returnValue = cont.parameters[0]; |
- setValue(returnValue, nonConstant()); |
+ setValue(returnValue, nonConstant(typeSystem.getReturnType(node.target))); |
} |
void visitConcatenateStrings(ConcatenateStrings node) { |
@@ -794,7 +822,11 @@ class _TypePropagationVisitor<T> implements Visitor { |
} |
void visitGetStatic(GetStatic node) { |
- setValue(node, nonConstant()); |
+ if (node.element.isFunction) { |
+ setValue(node, nonConstant(typeSystem.functionType)); |
+ } else { |
+ setValue(node, nonConstant(typeSystem.getFieldType(node.element))); |
+ } |
} |
void visitSetStatic(SetStatic node) { |
@@ -807,7 +839,7 @@ class _TypePropagationVisitor<T> implements Visitor { |
assert(cont.parameters.length == 1); |
Parameter returnValue = cont.parameters[0]; |
- setValue(returnValue, nonConstant()); |
+ setValue(returnValue, nonConstant(typeSystem.getFieldType(node.element))); |
} |
void visitIsTrue(IsTrue node) { |
@@ -841,12 +873,12 @@ class _TypePropagationVisitor<T> implements Visitor { |
setReachable(node.input.definition); |
_AbstractValue<T> value = getValue(node.input.definition); |
if (!value.isNothing) { |
- setValue(node, nonConstant()); |
+ setValue(node, nonConstant(typeSystem.nonNullType)); |
} |
} |
void visitGetField(GetField node) { |
- setValue(node, nonConstant()); |
+ setValue(node, nonConstant(typeSystem.getFieldType(node.field))); |
} |
void visitSetField(SetField node) { |
@@ -854,11 +886,11 @@ class _TypePropagationVisitor<T> implements Visitor { |
} |
void visitCreateBox(CreateBox node) { |
- setValue(node, nonConstant()); |
+ setValue(node, nonConstant(typeSystem.nonNullType)); |
} |
void visitCreateInstance(CreateInstance node) { |
- setValue(node, nonConstant()); |
+ setValue(node, nonConstant(typeSystem.exact(node.classElement))); |
} |
void visitReifyRuntimeType(ReifyRuntimeType node) { |
@@ -879,7 +911,8 @@ class _TypePropagationVisitor<T> implements Visitor { |
} |
void visitCreateInvocationMirror(CreateInvocationMirror node) { |
- setValue(node, nonConstant()); |
+ // TODO(asgerf): Expose [Invocation] type. |
+ setValue(node, nonConstant(typeSystem.nonNullType)); |
} |
} |
@@ -960,6 +993,13 @@ class _AbstractValue<T> { |
if (kind == NOTHING) return true; |
return typeSystem.isDefinitelyBool(type); |
} |
+ |
+ /// True if null is not a member of this value. |
+ bool isDefinitelyNotNull(TypeSystem<T> typeSystem) { |
+ if (kind == NOTHING) return true; |
+ if (kind == CONSTANT) return !constant.isNull; |
+ return typeSystem.isDefinitelyNotNull(type); |
+ } |
} |
class ConstantExpressionCreator |