Index: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
index 1e469ed9c52940c1b7ba632132c7bb18648b1417..d6166bb6d7cd19df6c99010186f337d04af2ab07 100644 |
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
@@ -13,11 +13,8 @@ import '../constants/values.dart'; |
import '../elements/elements.dart'; |
import '../elements/entities.dart'; |
import '../elements/resolution_types.dart' |
- show |
- ResolutionDartType, |
- ResolutionFunctionType, |
- ResolutionInterfaceType, |
- ResolutionTypeKind; |
+ show ResolutionDartType, ResolutionInterfaceType; |
+import '../elements/types.dart'; |
import '../tree/tree.dart' as ast show Node, Send; |
import '../types/masks.dart' |
show |
@@ -370,7 +367,7 @@ abstract class ElementTypeInformation extends TypeInformation { |
* These should never be created directly but instead are constructed by |
* the [ElementTypeInformation] factory. |
*/ |
-class MemberTypeInformation extends ElementTypeInformation |
+abstract class MemberTypeInformation extends ElementTypeInformation |
with ApplyableTypeInformation { |
MemberElement get _member => super._element; |
@@ -396,7 +393,8 @@ class MemberTypeInformation extends ElementTypeInformation |
*/ |
Map<MemberElement, Setlet<Spannable>> _callers; |
- MemberTypeInformation(MemberElement element) : super._internal(null, element); |
+ MemberTypeInformation._internal(MemberElement element) |
+ : super._internal(null, element); |
MemberElement get member => _element; |
@@ -455,59 +453,19 @@ class MemberTypeInformation extends ElementTypeInformation |
// state of the [isStable] field inherited from [TypeInformation]. |
bool get isStable => super.isStable && !isClosurized; |
- TypeMask handleSpecialCases(InferrerEngine inferrer) { |
- if (_member.isField && |
- (!inferrer.backend.canFieldBeUsedForGlobalOptimizations( |
- _member, inferrer.closedWorld) || |
- inferrer.assumeDynamic(_member))) { |
- // Do not infer types for fields that have a corresponding annotation or |
- // are assigned by synthesized calls |
+ TypeMask handleSpecialCases(InferrerEngine inferrer); |
- giveUp(inferrer); |
- return safeType(inferrer); |
- } |
- if (inferrer.closedWorld.nativeData.isNativeMember(_member)) { |
+ TypeMask _handleFunctionCase( |
+ FunctionEntity function, InferrerEngine inferrer) { |
+ if (inferrer.closedWorld.nativeData.isNativeMember(function)) { |
// Use the type annotation as the type for native elements. We |
// also give up on inferring to make sure this element never |
// goes in the work queue. |
giveUp(inferrer); |
- if (_member.isField) { |
- FieldElement field = _member; |
- return inferrer |
- .typeOfNativeBehavior(inferrer.closedWorld.nativeData |
- .getNativeFieldLoadBehavior(field)) |
- .type; |
- } else { |
- assert(_member.isFunction || |
- _member.isGetter || |
- _member.isSetter || |
- _member.isConstructor); |
- MethodElement methodElement = _member; |
- var elementType = methodElement.type; |
- if (elementType.kind != ResolutionTypeKind.FUNCTION) { |
- return safeType(inferrer); |
- } else { |
- return inferrer |
- .typeOfNativeBehavior(inferrer.closedWorld.nativeData |
- .getNativeMethodBehavior(methodElement)) |
- .type; |
- } |
- } |
- } |
- |
- CommonMasks commonMasks = inferrer.commonMasks; |
- if (_member.isConstructor) { |
- ConstructorElement constructor = _member; |
- if (constructor.isIntFromEnvironmentConstructor) { |
- giveUp(inferrer); |
- return commonMasks.intType.nullable(); |
- } else if (constructor.isBoolFromEnvironmentConstructor) { |
- giveUp(inferrer); |
- return commonMasks.boolType.nullable(); |
- } else if (constructor.isStringFromEnvironmentConstructor) { |
- giveUp(inferrer); |
- return commonMasks.stringType.nullable(); |
- } |
+ return inferrer |
+ .typeOfNativeBehavior( |
+ inferrer.closedWorld.nativeData.getNativeMethodBehavior(function)) |
+ .type; |
} |
return null; |
} |
@@ -519,19 +477,11 @@ class MemberTypeInformation extends ElementTypeInformation |
!inferrer.trustTypeAnnotations(_member)) { |
return mask; |
} |
- if (_member.isGenerativeConstructor || _member.isSetter) { |
- return mask; |
- } |
- if (_member.isField) { |
- return _narrowType(inferrer.closedWorld, mask, _member.type); |
- } |
- assert( |
- _member.isFunction || _member.isGetter || _member.isFactoryConstructor); |
- |
- ResolutionFunctionType type = _member.type; |
- return _narrowType(inferrer.closedWorld, mask, type.returnType); |
+ return _potentiallyNarrowType(mask, inferrer); |
} |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer); |
+ |
TypeMask computeType(InferrerEngine inferrer) { |
TypeMask special = handleSpecialCases(inferrer); |
if (special != null) return potentiallyNarrowType(special, inferrer); |
@@ -549,29 +499,155 @@ class MemberTypeInformation extends ElementTypeInformation |
return visitor.visitMemberTypeInformation(this); |
} |
+ void cleanup() { |
+ // This node is on multiple lists so cleanup() can be called twice. |
+ if (_isCalledOnce != null) return; |
+ _isCalledOnce = _computeIsCalledOnce(); |
+ _callers = null; |
+ super.cleanup(); |
+ } |
+ |
+ @override |
+ String getInferredSignature(TypeSystem types) { |
+ return types.getInferredSignatureOfMethod(_member); |
+ } |
+} |
+ |
+class FieldTypeInformation extends MemberTypeInformation { |
+ FieldElement get _field => _member; |
+ |
+ FieldTypeInformation(FieldElement element) : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ if (!inferrer.backend.canFieldBeUsedForGlobalOptimizations( |
+ _field, inferrer.closedWorld) || |
+ inferrer.assumeDynamic(_field)) { |
+ // Do not infer types for fields that have a corresponding annotation or |
+ // are assigned by synthesized calls |
+ |
+ giveUp(inferrer); |
+ return safeType(inferrer); |
+ } |
+ if (inferrer.closedWorld.nativeData.isNativeMember(_field)) { |
+ // Use the type annotation as the type for native elements. We |
+ // also give up on inferring to make sure this element never |
+ // goes in the work queue. |
+ giveUp(inferrer); |
+ return inferrer |
+ .typeOfNativeBehavior(inferrer.closedWorld.nativeData |
+ .getNativeFieldLoadBehavior(_field)) |
+ .type; |
+ } |
+ return null; |
+ } |
+ |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ return _narrowType(inferrer.closedWorld, mask, _field.type); |
+ } |
+ |
bool hasStableType(InferrerEngine inferrer) { |
// The number of assignments of non-final fields is |
// not stable. Therefore such a field cannot be stable. |
- if (_member.isField && !(_member.isConst || _member.isFinal)) { |
+ if (!(_field.isConst || _field.isFinal)) { |
return false; |
} |
+ return super.hasStableType(inferrer); |
+ } |
+} |
+ |
+class GetterTypeInformation extends MemberTypeInformation { |
+ GetterElement get _getter => _member; |
+ |
+ GetterTypeInformation(GetterElement element) : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ return _handleFunctionCase(_getter, inferrer); |
+ } |
+ |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ FunctionType type = _getter.type; |
+ return _narrowType(inferrer.closedWorld, mask, type.returnType); |
+ } |
+} |
+ |
+class SetterTypeInformation extends MemberTypeInformation { |
+ SetterElement get _setter => _member; |
+ |
+ SetterTypeInformation(SetterElement element) : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ return _handleFunctionCase(_setter, inferrer); |
+ } |
+ |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ return mask; |
+ } |
+} |
+ |
+class MethodTypeInformation extends MemberTypeInformation { |
+ MethodElement get _method => _member; |
+ |
+ MethodTypeInformation(MethodElement element) : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ return _handleFunctionCase(_method, inferrer); |
+ } |
+ |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ FunctionType type = _method.type; |
+ return _narrowType(inferrer.closedWorld, mask, type.returnType); |
+ } |
+ |
+ bool hasStableType(InferrerEngine inferrer) => false; |
+} |
+ |
+class FactoryConstructorTypeInformation extends MemberTypeInformation { |
+ ConstructorElement get _constructor => _member; |
+ |
+ FactoryConstructorTypeInformation(ConstructorElement element) |
+ : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ CommonMasks commonMasks = inferrer.commonMasks; |
+ if (_constructor.isIntFromEnvironmentConstructor) { |
+ giveUp(inferrer); |
+ return commonMasks.intType.nullable(); |
+ } else if (_constructor.isBoolFromEnvironmentConstructor) { |
+ giveUp(inferrer); |
+ return commonMasks.boolType.nullable(); |
+ } else if (_constructor.isStringFromEnvironmentConstructor) { |
+ giveUp(inferrer); |
+ return commonMasks.stringType.nullable(); |
+ } |
+ return _handleFunctionCase(_constructor, inferrer); |
+ } |
- if (_member.isFunction) return false; |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ FunctionType type = _constructor.type; |
+ return _narrowType(inferrer.closedWorld, mask, type.returnType); |
+ } |
+ bool hasStableType(InferrerEngine inferrer) { |
return super.hasStableType(inferrer); |
} |
+} |
- void cleanup() { |
- // This node is on multiple lists so cleanup() can be called twice. |
- if (_isCalledOnce != null) return; |
- _isCalledOnce = _computeIsCalledOnce(); |
- _callers = null; |
- super.cleanup(); |
+class GenerativeConstructorTypeInformation extends MemberTypeInformation { |
+ ConstructorElement get _constructor => _member; |
+ |
+ GenerativeConstructorTypeInformation(ConstructorElement element) |
+ : super._internal(element); |
+ |
+ TypeMask handleSpecialCases(InferrerEngine inferrer) { |
+ return _handleFunctionCase(_constructor, inferrer); |
} |
- @override |
- String getInferredSignature(TypeSystem types) { |
- return types.getInferredSignatureOfMethod(_member); |
+ TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
+ return mask; |
+ } |
+ |
+ bool hasStableType(InferrerEngine inferrer) { |
+ return super.hasStableType(inferrer); |
} |
} |
@@ -591,8 +667,8 @@ class ParameterTypeInformation extends ElementTypeInformation { |
bool _isClosureParameter; |
bool _isTearOffClosureParameter = false; |
- ParameterTypeInformation.localFunction(MemberTypeInformation context, |
- ParameterElement parameter, this._method) |
+ ParameterTypeInformation.localFunction( |
+ MemberTypeInformation context, ParameterElement parameter, this._method) |
: _isInstanceMemberParameter = false, |
_isClosureParameter = true, |
super._internal(context, parameter); |