Index: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
index f2f8e0b9685214dca46c156e2d157f5fb6326bbf..4e96cd6adde5b0e5ab729d787e56ce1814334580 100644 |
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
@@ -18,7 +18,7 @@ import '../native/native.dart' as native; |
import '../resolution/operators.dart' as op; |
import '../resolution/tree_elements.dart' show TreeElements; |
import '../tree/tree.dart' as ast; |
-import '../types/types.dart' show TypeMask; |
+import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData; |
import '../universe/call_structure.dart' show CallStructure; |
import '../universe/selector.dart' show Selector; |
import '../universe/side_effects.dart' show SideEffects; |
@@ -39,6 +39,11 @@ abstract class InferrerEngine<T, V extends TypeSystem> |
final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>(); |
final Set<Element> generativeConstructorsExposingThis = new Set<Element>(); |
+ /// Data computed internally within elements, like the type-mask of a send a |
+ /// list allocation, or a for-in loop. |
+ final Map<Element, GlobalTypeInferenceElementData> inTreeData = |
+ new Map<Element, GlobalTypeInferenceElementData>(); |
+ |
InferrerEngine(Compiler compiler, this.types) |
: this.compiler = compiler, |
this.closedWorld = compiler.closedWorld; |
@@ -181,6 +186,9 @@ abstract class InferrerEngine<T, V extends TypeSystem> |
} |
} |
+ GlobalTypeInferenceElementData _dataOf(AstElement element) => inTreeData |
+ .putIfAbsent(element, () => new GlobalTypeInferenceElementData()); |
+ |
/** |
* Update [sideEffects] with the side effects of [callee] being |
* called with [selector]. |
@@ -261,27 +269,27 @@ abstract class InferrerEngine<T, V extends TypeSystem> |
void updateSelectorInTree( |
AstElement owner, Spannable node, Selector selector, TypeMask mask) { |
ast.Node astNode = node; |
- TreeElements elements = owner.resolvedAst.elements; |
+ GlobalTypeInferenceElementData data = _dataOf(owner); |
if (astNode.asSendSet() != null) { |
if (selector.isSetter || selector.isIndexSet) { |
- elements.setTypeMask(node, mask); |
+ data.setTypeMask(node, mask); |
} else if (selector.isGetter || selector.isIndex) { |
- elements.setGetterTypeMaskInComplexSendSet(node, mask); |
+ data.setGetterTypeMaskInComplexSendSet(node, mask); |
} else { |
assert(selector.isOperator); |
- elements.setOperatorTypeMaskInComplexSendSet(node, mask); |
+ data.setOperatorTypeMaskInComplexSendSet(node, mask); |
} |
} else if (astNode.asSend() != null) { |
- elements.setTypeMask(node, mask); |
+ data.setTypeMask(node, mask); |
} else { |
assert(astNode.asForIn() != null); |
if (selector == Selectors.iterator) { |
- elements.setIteratorTypeMask(node, mask); |
+ data.setIteratorTypeMask(node, mask); |
} else if (selector == Selectors.current) { |
- elements.setCurrentTypeMask(node, mask); |
+ data.setCurrentTypeMask(node, mask); |
} else { |
assert(selector == Selectors.moveNext); |
- elements.setMoveNextTypeMask(node, mask); |
+ data.setMoveNextTypeMask(node, mask); |
} |
} |
} |
@@ -324,6 +332,7 @@ class SimpleTypeInferrerVisitor<T> |
final Element outermostElement; |
final InferrerEngine<T, TypeSystem<T>> inferrer; |
final Setlet<Entity> capturedVariables = new Setlet<Entity>(); |
+ final GlobalTypeInferenceElementData inTreeData; |
SimpleTypeInferrerVisitor.internal( |
AstElement analyzedElement, |
@@ -334,7 +343,8 @@ class SimpleTypeInferrerVisitor<T> |
locals) |
: super(analyzedElement, resolvedAst, inferrer, inferrer.types, compiler, |
locals), |
- this.inferrer = inferrer { |
+ this.inferrer = inferrer, |
+ this.inTreeData = inferrer._dataOf(analyzedElement) { |
assert(outermostElement != null); |
} |
@@ -693,10 +703,10 @@ class SimpleTypeInferrerVisitor<T> |
} |
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
- TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
- TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); |
+ TypeMask getterMask = inTreeData.typeOfGetter(node); |
+ TypeMask operatorMask = inTreeData.typeOfOperator(node); |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
String op = node.assignmentOperator.source; |
bool isIncrementOrDecrement = op == '++' || op == '--'; |
@@ -806,12 +816,13 @@ class SimpleTypeInferrerVisitor<T> |
T handleCompoundIndexSet( |
ast.SendSet node, T receiverType, T indexType, T rhsType) { |
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
- TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
+ |
+ TypeMask getterMask = inTreeData.typeOfGetter(node); |
Selector operatorSelector = |
elements.getOperatorSelectorInComplexSendSet(node); |
- TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); |
+ TypeMask operatorMask = inTreeData.typeOfOperator(node); |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
T getterType = handleDynamicSend(node, getterSelector, getterMask, |
receiverType, new ArgumentsTypes<T>([indexType], null)); |
@@ -906,9 +917,10 @@ class SimpleTypeInferrerVisitor<T> |
T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, |
Element setter, T indexType, T rhsType) { |
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
- TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
+ |
+ TypeMask getterMask = inTreeData.typeOfGetter(node); |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
T getterType = handleSuperSend(node, getterSelector, getterMask, getter, |
new ArgumentsTypes<T>([indexType], null)); |
@@ -919,8 +931,7 @@ class SimpleTypeInferrerVisitor<T> |
} else { |
Selector operatorSelector = |
elements.getOperatorSelectorInComplexSendSet(node); |
- TypeMask operatorMask = |
- elements.getOperatorTypeMaskInComplexSendSet(node); |
+ TypeMask operatorMask = inTreeData.typeOfOperator(node); |
returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
getterType, new ArgumentsTypes<T>([rhsType], null)); |
} |
@@ -1268,9 +1279,9 @@ class SimpleTypeInferrerVisitor<T> |
T _handleSuperCompound( |
ast.SendSet node, Element getter, Element setter, T rhsType) { |
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
- TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
+ TypeMask getterMask = inTreeData.typeOfGetter(node); |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
T getterType = |
handleSuperSend(node, getterSelector, getterMask, getter, null); |
@@ -1281,8 +1292,7 @@ class SimpleTypeInferrerVisitor<T> |
} else { |
Selector operatorSelector = |
elements.getOperatorSelectorInComplexSendSet(node); |
- TypeMask operatorMask = |
- elements.getOperatorTypeMaskInComplexSendSet(node); |
+ TypeMask operatorMask = inTreeData.typeOfOperator(node); |
returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
getterType, new ArgumentsTypes<T>([rhsType], null)); |
} |
@@ -1295,7 +1305,7 @@ class SimpleTypeInferrerVisitor<T> |
/// Handle index set, like `foo[0] = 42`. |
T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) { |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
handleDynamicSend(node, setterSelector, setterMask, receiverType, |
new ArgumentsTypes<T>([indexType, rhsType], null)); |
return rhsType; |
@@ -1316,7 +1326,7 @@ class SimpleTypeInferrerVisitor<T> |
T indexType = visit(index); |
T rhsType = visit(rhs); |
Selector setterSelector = elements.getSelector(node); |
- TypeMask setterMask = elements.getTypeMask(node); |
+ TypeMask setterMask = inTreeData.typeOfSend(node); |
handleStaticSend(node, setterSelector, setterMask, element, |
new ArgumentsTypes<T>([indexType, rhsType], null)); |
return rhsType; |
@@ -1392,7 +1402,7 @@ class SimpleTypeInferrerVisitor<T> |
ArgumentsTypes arguments = |
node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
// TODO(herhut): We could do better here if we knew what we |
// are calling does not expose this. |
// TODO(johnniwinther): Do we still need this when calling directly? |
@@ -1419,7 +1429,7 @@ class SimpleTypeInferrerVisitor<T> |
ast.Send node, Element element, ast.NodeList arguments) { |
ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
// TODO(herhut): We could do better here if we knew what we |
// are calling does not expose this. |
isThisExposed = true; |
@@ -1441,7 +1451,7 @@ class SimpleTypeInferrerVisitor<T> |
// are calling does not expose this. |
isThisExposed = true; |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, method, arguments); |
} |
@@ -1451,7 +1461,7 @@ class SimpleTypeInferrerVisitor<T> |
// are calling does not expose this. |
isThisExposed = true; |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, element, null); |
} |
@@ -1462,7 +1472,7 @@ class SimpleTypeInferrerVisitor<T> |
// are calling does not expose this. |
isThisExposed = true; |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend( |
node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null)); |
} |
@@ -1674,7 +1684,7 @@ class SimpleTypeInferrerVisitor<T> |
return handleForeignSend(node, target); |
} |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
// In erroneous code the number of arguments in the selector might not |
// match the function element. |
// TODO(polux): return nonNullEmpty and check it doesn't break anything |
@@ -1733,7 +1743,7 @@ class SimpleTypeInferrerVisitor<T> |
T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) { |
ArgumentsTypes arguments = analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
handleStaticSend(node, selector, mask, element, arguments); |
return inferrer.registerCalledClosure( |
node, |
@@ -1753,7 +1763,7 @@ class SimpleTypeInferrerVisitor<T> |
} |
ArgumentsTypes arguments = analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, function, arguments); |
} |
@@ -1837,7 +1847,7 @@ class SimpleTypeInferrerVisitor<T> |
T handleForeignSend(ast.Send node, Element element) { |
ArgumentsTypes arguments = analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
String name = element.name; |
handleStaticSend(node, selector, mask, element, arguments); |
if (name == BackendHelpers.JS || |
@@ -1882,21 +1892,21 @@ class SimpleTypeInferrerVisitor<T> |
/// Read a static or top level field. |
T handleStaticFieldGet(ast.Send node, FieldElement field) { |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, field, null); |
} |
/// Invoke a static or top level getter. |
T handleStaticGetterGet(ast.Send node, MethodElement getter) { |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, getter, null); |
} |
/// Closurize a static or top level function. |
T handleStaticFunctionGet(ast.Send node, MethodElement function) { |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return handleStaticSend(node, selector, mask, function, null); |
} |
@@ -1980,7 +1990,7 @@ class SimpleTypeInferrerVisitor<T> |
T handleCallInvoke(ast.Send node, T closure) { |
ArgumentsTypes arguments = analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
return inferrer.registerCalledClosure(node, selector, mask, closure, |
outermostElement, arguments, sideEffects, inLoop); |
} |
@@ -2014,7 +2024,7 @@ class SimpleTypeInferrerVisitor<T> |
ast.NodeList arguments, CallStructure callStructure, _) { |
ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
// This only works for function statements. We need a |
// more sophisticated type system with function types to support |
// more. |
@@ -2100,7 +2110,7 @@ class SimpleTypeInferrerVisitor<T> |
} |
Selector selector = elements.getSelector(node); |
- TypeMask mask = elements.getTypeMask(node); |
+ TypeMask mask = inTreeData.typeOfSend(node); |
if (!isThisExposed && isCallOnThis) { |
checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); |
} |
@@ -2195,7 +2205,7 @@ class SimpleTypeInferrerVisitor<T> |
ast.Node identifier = node.declaredIdentifier; |
Element element = elements.getForInVariable(node); |
Selector selector = elements.getSelector(identifier); |
- TypeMask mask = elements.getTypeMask(identifier); |
+ TypeMask mask = inTreeData.typeOfSend(identifier); |
T receiverType; |
if (element != null && element.isInstanceMember) { |
@@ -2215,9 +2225,9 @@ class SimpleTypeInferrerVisitor<T> |
T expressionType = visit(node.expression); |
Selector currentSelector = Selectors.current; |
- TypeMask currentMask = elements.getCurrentTypeMask(node); |
+ TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); |
Selector moveNextSelector = Selectors.moveNext; |
- TypeMask moveNextMask = elements.getMoveNextTypeMask(node); |
+ TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
js.JavaScriptBackend backend = compiler.backend; |
Element ctor = backend.helpers.streamIteratorConstructor; |
@@ -2233,11 +2243,11 @@ class SimpleTypeInferrerVisitor<T> |
T visitSyncForIn(ast.SyncForIn node) { |
T expressionType = visit(node.expression); |
Selector iteratorSelector = Selectors.iterator; |
- TypeMask iteratorMask = elements.getIteratorTypeMask(node); |
+ TypeMask iteratorMask = inTreeData.typeOfIterator(node); |
Selector currentSelector = Selectors.current; |
- TypeMask currentMask = elements.getCurrentTypeMask(node); |
+ TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); |
Selector moveNextSelector = Selectors.moveNext; |
- TypeMask moveNextMask = elements.getMoveNextTypeMask(node); |
+ TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask, |
expressionType, new ArgumentsTypes<T>.empty()); |