Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
index b29c9c7823550ebfe6e5084313a63f3a1097fd50..3bfeed456686a7f73bb206602e37e4d153e6f6f2 100644 |
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
@@ -17,7 +17,6 @@ import '../js_backend/js_backend.dart' show JavaScriptBackend; |
import '../resolution/semantic_visitor.dart'; |
import '../resolution/operators.dart' as op; |
import '../tree/tree.dart' as ast; |
-import '../types/types.dart' show TypeMask; |
import '../universe/universe.dart' show SelectorKind, CallStructure; |
import 'cps_ir_nodes.dart' as ir; |
import 'cps_ir_builder.dart'; |
@@ -167,6 +166,28 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
/// Read the value of [field]. |
ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src); |
+ /// Creates a [TypedSelector] variant of [newSelector] using the type of |
+ /// [oldSelector], if available. |
+ /// |
+ /// This is needed to preserve inferred receiver types when creating new |
+ /// selectors. |
+ Selector useSelectorType(Selector newSelector, Selector oldSelector) { |
+ // TODO(asgerf,johnniwinther): This works but it is brittle. |
+ // We should decouple selectors from inferred receiver type masks. |
+ // TODO(asgerf): Use this whenever we create a selector for a dynamic call. |
+ if (oldSelector is TypedSelector) { |
+ return new TypedSelector(oldSelector.mask, newSelector, compiler.world); |
+ } else { |
+ return newSelector; |
+ } |
+ } |
+ |
+ /// Like [useSelectorType], except the original typed selector is obtained |
+ /// from the [node]. |
+ Selector useSelectorTypeOfNode(Selector newSelector, ast.Send node) { |
+ return useSelectorType(newSelector, elements.getSelector(node)); |
+ } |
+ |
ir.FunctionDefinition _makeFunctionBody(FunctionElement element, |
ast.FunctionExpression node) { |
FunctionSignature signature = element.functionSignature; |
@@ -313,10 +334,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
buildVariableDeclaration: subbuild(variableDeclaration), |
variableElement: variableElement, |
variableSelector: selector, |
- variableMask: elements.getTypeMask(identifier), |
- currentMask: elements.getCurrentTypeMask(node), |
- moveNextMask: elements.getMoveNextTypeMask(node), |
- iteratorMask: elements.getIteratorTypeMask(node), |
buildBody: subbuild(node.body), |
target: elements.getTargetDefinition(node), |
closureScope: getClosureScopeForNode(node)); |
@@ -564,8 +581,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
_) { |
return irBuilder.buildDynamicGet( |
translateReceiver(receiver), |
- selector, |
- elements.getTypeMask(node)); |
+ selector); |
} |
@override |
@@ -577,8 +593,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive target = visit(receiver); |
return irBuilder.buildIfNotNullSend( |
target, |
- nested(() => irBuilder.buildDynamicGet( |
- target, selector, elements.getTypeMask(node)))); |
+ nested(() => irBuilder.buildDynamicGet(target, selector))); |
} |
@override |
@@ -663,8 +678,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive visitUnresolvedSuperGet( |
ast.Send node, |
Element element, _) { |
- return buildInstanceNoSuchMethod( |
- elements.getSelector(node), elements.getTypeMask(node), []); |
+ return buildInstanceNoSuchMethod(elements.getSelector(node), []); |
} |
@override |
@@ -752,12 +766,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ast.Node left, |
op.BinaryOperator operator, |
ast.Node right) { |
- Selector selector = new Selector.binaryOperator(operator.selectorName); |
+ Selector selector = useSelectorTypeOfNode( |
+ new Selector.binaryOperator(operator.selectorName), |
+ node); |
ir.Primitive receiver = visit(left); |
List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; |
arguments = normalizeDynamicArguments(selector.callStructure, arguments); |
- return irBuilder.buildDynamicInvocation( |
- receiver, selector, elements.getTypeMask(node), arguments); |
+ return irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
} |
@override |
@@ -772,12 +787,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive visitIndex(ast.Send node, |
ast.Node receiver, |
ast.Node index, _) { |
- Selector selector = new Selector.index(); |
+ Selector selector = useSelectorTypeOfNode(new Selector.index(), node); |
ir.Primitive target = visit(receiver); |
List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; |
arguments = normalizeDynamicArguments(selector.callStructure, arguments); |
- return irBuilder.buildDynamicInvocation( |
- target, selector, elements.getTypeMask(node), arguments); |
+ return irBuilder.buildDynamicInvocation(target, selector, arguments); |
} |
ir.Primitive translateSuperBinary(FunctionElement function, |
@@ -861,8 +875,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
// TODO(johnniwinther): Clean up the creation of selectors. |
Selector selector = operator.selector; |
ir.Primitive receiver = translateReceiver(expression); |
- return irBuilder.buildDynamicInvocation( |
- receiver, selector, elements.getTypeMask(node), const []); |
+ return irBuilder.buildDynamicInvocation(receiver, selector, const []); |
} |
@override |
@@ -919,7 +932,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
Selector selector, |
_) { |
return irBuilder.buildDynamicInvocation( |
- translateReceiver(receiver), selector, elements.getTypeMask(node), |
+ translateReceiver(receiver), selector, |
translateDynamicArguments(arguments, selector.callStructure)); |
} |
@@ -934,7 +947,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
return irBuilder.buildIfNotNullSend( |
target, |
nested(() => irBuilder.buildDynamicInvocation( |
- target, selector, elements.getTypeMask(node), |
+ target, selector, |
translateDynamicArguments(arguments, selector.callStructure)))); |
} |
@@ -1066,7 +1079,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
CallStructure callStructure, _) { |
return buildInstanceNoSuchMethod( |
elements.getSelector(node), |
- elements.getTypeMask(node), |
translateDynamicArguments(arguments, callStructure)); |
} |
@@ -1078,7 +1090,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
Selector selector, _) { |
return buildInstanceNoSuchMethod( |
elements.getSelector(node), |
- elements.getTypeMask(node), |
translateDynamicArguments(arguments, selector.callStructure)); |
} |
@@ -1112,7 +1123,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ast.Node rhs, |
_) { |
return irBuilder.buildDynamicIndexSet( |
- visit(receiver), elements.getTypeMask(node), visit(index), visit(rhs)); |
+ visit(receiver), visit(index), visit(rhs)); |
} |
@override |
@@ -1152,10 +1163,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
List<ir.Primitive> arguments = <ir.Primitive>[rhsValue]; |
arguments = normalizeDynamicArguments( |
operatorSelector.callStructure, arguments); |
- // TODO(johnniwinther): Find the type mask for the operation. |
ir.Primitive result = |
- irBuilder.buildDynamicInvocation( |
- value, operatorSelector, null, arguments); |
+ irBuilder.buildDynamicInvocation(value, operatorSelector, arguments); |
setValue(result); |
return rhs.kind == CompoundKind.POSTFIX ? value : result; |
} |
@@ -1170,7 +1179,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
return irBuilder.buildDynamicSet( |
translateReceiver(receiver), |
selector, |
- elements.getTypeMask(node), |
visit(rhs)); |
} |
@@ -1184,8 +1192,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive target = visit(receiver); |
return irBuilder.buildIfNotNullSend( |
target, |
- nested(() => irBuilder.buildDynamicSet( |
- target, selector, elements.getTypeMask(node), visit(rhs)))); |
+ nested(() => irBuilder.buildDynamicSet(target, selector, visit(rhs)))); |
} |
@override |
@@ -1257,7 +1264,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
@override |
ir.Primitive handleDynamicCompounds( |
- ast.SendSet node, |
+ ast.Send node, |
ast.Node receiver, |
CompoundRhs rhs, |
Selector getterSelector, |
@@ -1266,14 +1273,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive target = translateReceiver(receiver); |
ir.Primitive helper() { |
return translateCompounds( |
- getValue: () => irBuilder.buildDynamicGet( |
- target, |
- getterSelector, |
- elements.getGetterTypeMaskInComplexSendSet(node)), |
+ getValue: () => irBuilder.buildDynamicGet(target, getterSelector), |
rhs: rhs, |
setValue: (ir.Primitive result) { |
- irBuilder.buildDynamicSet( |
- target, setterSelector, elements.getTypeMask(node), result); |
+ irBuilder.buildDynamicSet(target, setterSelector, result); |
}); |
} |
return node.isConditional |
@@ -1361,19 +1364,15 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
}); |
} |
- ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) { |
+ ir.Primitive buildSuperNoSuchGetter(Element element) { |
return buildInstanceNoSuchMethod( |
new Selector.getter(element.name, element.library), |
- mask, |
const <ir.Primitive>[]); |
} |
- ir.Primitive buildSuperNoSuchSetter(Element element, |
- TypeMask mask, |
- ir.Primitive value) { |
+ ir.Primitive buildSuperNoSuchSetter(Element element, ir.Primitive value) { |
return buildInstanceNoSuchMethod( |
new Selector.setter(element.name, element.library), |
- mask, |
<ir.Primitive>[value]); |
} |
@@ -1397,9 +1396,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
return irBuilder.buildSuperMethodGet(getter); |
case CompoundGetter.UNRESOLVED: |
// TODO(johnniwinther): Ensure [getter] is not null. |
- return buildSuperNoSuchGetter( |
- getter != null ? getter : setter, |
- elements.getGetterTypeMaskInComplexSendSet(node)); |
+ return buildSuperNoSuchGetter(getter != null ? getter : setter); |
} |
}, |
rhs: rhs, |
@@ -1410,8 +1407,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
case CompoundSetter.SETTER: |
return irBuilder.buildSuperSetterSet(setter, result); |
case CompoundSetter.INVALID: |
- return buildSuperNoSuchSetter( |
- setter, elements.getTypeMask(node), result); |
+ return buildSuperNoSuchSetter(setter, result); |
} |
}); |
} |
@@ -1443,19 +1439,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
arguments = |
normalizeDynamicArguments(selector.callStructure, arguments); |
- return irBuilder.buildDynamicInvocation( |
- target, |
- selector, |
- elements.getGetterTypeMaskInComplexSendSet(node), |
- arguments); |
+ return irBuilder.buildDynamicInvocation(target, selector, arguments); |
}, |
rhs: rhs, |
setValue: (ir.Primitive result) { |
- irBuilder.buildDynamicIndexSet( |
- target, |
- elements.getTypeMask(node), |
- indexValue, |
- result); |
+ irBuilder.buildDynamicIndexSet(target, indexValue, result); |
}); |
} |
@@ -1476,9 +1464,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
return irBuilder.buildSuperIndex(indexFunction, indexValue); |
} else { |
return buildInstanceNoSuchMethod( |
- new Selector.index(), |
- elements.getGetterTypeMaskInComplexSendSet(node), |
- <ir.Primitive>[indexValue]); |
+ new Selector.index(), <ir.Primitive>[indexValue]); |
} |
}, |
rhs: rhs, |
@@ -1487,9 +1473,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result); |
} else { |
buildInstanceNoSuchMethod( |
- new Selector.indexSet(), |
- elements.getTypeMask(node), |
- <ir.Primitive>[indexValue, result]); |
+ new Selector.indexSet(), <ir.Primitive>[indexValue, result]); |
} |
}); |
} |
@@ -1532,7 +1516,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ir.Primitive buildInstanceNoSuchMethod( |
Selector selector, |
- TypeMask mask, |
List<ir.Primitive> arguments); |
ir.Primitive buildRuntimeError(String message); |
@@ -1651,8 +1634,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
Element function, |
ast.Node index, _) { |
// Assume the index getter is missing. |
- return buildInstanceNoSuchMethod( |
- new Selector.index(), elements.getTypeMask(node), [visit(index)]); |
+ Selector selector = useSelectorTypeOfNode(new Selector.index(), node); |
+ return buildInstanceNoSuchMethod(selector, [visit(index)]); |
} |
@override |
@@ -1663,7 +1646,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ast.Node argument, _) { |
return buildInstanceNoSuchMethod( |
elements.getSelector(node), |
- elements.getTypeMask(node), |
[visit(argument)]); |
} |
@@ -1672,8 +1654,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ast.Send node, |
op.UnaryOperator operator, |
Element element, _) { |
- return buildInstanceNoSuchMethod( |
- elements.getSelector(node), elements.getTypeMask(node), []); |
+ return buildInstanceNoSuchMethod(elements.getSelector(node), []); |
} |
@override |
@@ -1761,10 +1742,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
ast.SendSet node, |
FieldElement field, |
ast.Node rhs, _) { |
- return buildInstanceNoSuchMethod( |
+ Selector selector = useSelectorTypeOfNode( |
new Selector.setter(field.name, field.library), |
- elements.getTypeMask(node), |
- [visit(rhs)]); |
+ node); |
+ return buildInstanceNoSuchMethod(selector, [visit(rhs)]); |
} |
@override |
@@ -1829,10 +1810,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
FunctionElement getter, |
ast.Node rhs, |
_) { |
- return buildInstanceNoSuchMethod( |
+ Selector selector = useSelectorTypeOfNode( |
new Selector.setter(getter.name, getter.library), |
- elements.getTypeMask(node), |
- [visit(rhs)]); |
+ node); |
+ return buildInstanceNoSuchMethod(selector, [visit(rhs)]); |
} |
@override |
@@ -1841,20 +1822,20 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
MethodElement method, |
ast.Node rhs, |
_) { |
- return buildInstanceNoSuchMethod( |
+ Selector selector = useSelectorTypeOfNode( |
new Selector.setter(method.name, method.library), |
- elements.getTypeMask(node), |
- [visit(rhs)]); |
+ node); |
+ return buildInstanceNoSuchMethod(selector, [visit(rhs)]); |
} |
@override |
ir.Primitive visitSuperSetterGet( |
ast.Send node, |
FunctionElement setter, _) { |
- return buildInstanceNoSuchMethod( |
+ Selector selector = useSelectorTypeOfNode( |
new Selector.setter(setter.name, setter.library), |
- elements.getTypeMask(node), |
- []); |
+ node); |
+ return buildInstanceNoSuchMethod(selector, []); |
} |
@override |
@@ -1866,10 +1847,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
List<ir.Primitive> args = |
translateDynamicArguments(arguments, callStructure); |
Name name = new Name(setter.name, setter.library); |
- return buildInstanceNoSuchMethod( |
+ Selector selector = useSelectorTypeOfNode( |
new Selector(SelectorKind.CALL, name, callStructure), |
- elements.getTypeMask(node), |
- args); |
+ node); |
+ return buildInstanceNoSuchMethod(selector, args); |
} |
ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { |
@@ -2789,12 +2770,10 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
@override |
ir.Primitive buildInstanceNoSuchMethod(Selector selector, |
- TypeMask mask, |
List<ir.Primitive> arguments) { |
return irBuilder.buildDynamicInvocation( |
irBuilder.buildThis(), |
- compiler.noSuchMethodSelector, |
- mask, |
+ useSelectorType(compiler.noSuchMethodSelector, selector), |
[irBuilder.buildInvocationMirror(selector, arguments)]); |
} |