| Index: pkg/compiler/lib/src/ssa/builder.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
|
| index b2b0dd7fbfe8da23ba0a8f63229472ed6b362946..3264099cd73d05080b19604aaf13e4e81397d05d 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder.dart
|
| @@ -4165,44 +4165,218 @@ class SsaBuilder extends NewResolvedVisitor {
|
| }
|
|
|
| visitSuperSend(ast.Send node) {
|
| + internalError(node, "Unexpected super send.");
|
| + }
|
| +
|
| + /// Generate a call to a super method or constructor.
|
| + void generateSuperInvoke(ast.Send node, FunctionElement function) {
|
| + // TODO(5347): Try to avoid the need for calling [implementation] before
|
| + // calling [makeStaticArgumentList].
|
| Selector selector = elements.getSelector(node);
|
| - Element element = elements[node];
|
| - if (Elements.isUnresolved(element)) {
|
| - List<HInstruction> arguments = <HInstruction>[];
|
| - if (!node.isPropertyAccess) {
|
| - addGenericSendArgumentsToList(node.arguments, arguments);
|
| - }
|
| - return generateSuperNoSuchMethodSend(node, selector, arguments);
|
| + assert(invariant(node,
|
| + selector.applies(function.implementation, compiler.world),
|
| + message: "$selector does not apply to ${function.implementation}"));
|
| + List<HInstruction> inputs =
|
| + makeStaticArgumentList(selector.callStructure,
|
| + node.arguments,
|
| + function.implementation);
|
| + push(buildInvokeSuper(selector, function, inputs));
|
| + }
|
| +
|
| + /// Access the value from the super [element].
|
| + void handleSuperGet(ast.Send node, Element element) {
|
| + Selector selector = elements.getSelector(node);
|
| + push(buildInvokeSuper(selector, element, const <HInstruction>[]));
|
| + }
|
| +
|
| + /// Invoke .call on the value retrieved from the super [element].
|
| + void handleSuperCallInvoke(ast.Send node, Element element) {
|
| + Selector selector = elements.getSelector(node);
|
| + HInstruction target =
|
| + buildInvokeSuper(selector, element, const <HInstruction>[]);
|
| + add(target);
|
| + generateCallInvoke(node, target);
|
| + }
|
| +
|
| + /// Invoke super [method].
|
| + void handleSuperMethodInvoke(
|
| + ast.Send node,
|
| + MethodElement method) {
|
| + generateSuperInvoke(node, method);
|
| + }
|
| +
|
| + /// Access an unresolved super property.
|
| + void handleUnresolvedSuperInvoke(ast.Send node) {
|
| + Selector selector = elements.getSelector(node);
|
| + List<HInstruction> arguments = <HInstruction>[];
|
| + if (!node.isPropertyAccess) {
|
| + addGenericSendArgumentsToList(node.arguments, arguments);
|
| }
|
| - List<HInstruction> inputs = <HInstruction>[];
|
| - if (node.isPropertyAccess) {
|
| - push(buildInvokeSuper(selector, element, inputs));
|
| - } else if (element.isFunction || element.isGenerativeConstructor) {
|
| - if (selector.applies(element, compiler.world)) {
|
| - // TODO(5347): Try to avoid the need for calling [implementation] before
|
| - // calling [makeStaticArgumentList].
|
| - FunctionElement function = element.implementation;
|
| - assert(selector.applies(function, compiler.world));
|
| - inputs = makeStaticArgumentList(selector.callStructure,
|
| - node.arguments,
|
| - function);
|
| - push(buildInvokeSuper(selector, element, inputs));
|
| - } else if (element.isGenerativeConstructor) {
|
| - generateWrongArgumentCountError(node, element, node.arguments);
|
| - } else {
|
| - addGenericSendArgumentsToList(node.arguments, inputs);
|
| - generateSuperNoSuchMethodSend(node, selector, inputs);
|
| - }
|
| + generateSuperNoSuchMethodSend(node, selector, arguments);
|
| + }
|
| +
|
| + /// Handle super constructor invocation.
|
| + @override
|
| + void handleSuperConstructorInvoke(ast.Send node) {
|
| + Selector selector = elements.getSelector(node);
|
| + Element element = elements[node];
|
| + if (selector.applies(element, compiler.world)) {
|
| + generateSuperInvoke(node, element);
|
| } else {
|
| - HInstruction target = buildInvokeSuper(selector, element, inputs);
|
| - add(target);
|
| - inputs = <HInstruction>[target];
|
| - addDynamicSendArgumentsToList(node, inputs);
|
| - Selector closureSelector = new Selector.callClosureFrom(selector);
|
| - push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType));
|
| + generateWrongArgumentCountError(node, element, node.arguments);
|
| }
|
| }
|
|
|
| + @override
|
| + void visitUnresolvedSuperIndex(
|
| + ast.Send node,
|
| + Element element,
|
| + ast.Node index,
|
| + _) {
|
| + handleUnresolvedSuperInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + void visitUnresolvedSuperUnary(
|
| + ast.Send node,
|
| + UnaryOperator operator,
|
| + Element element,
|
| + _) {
|
| + handleUnresolvedSuperInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + void visitUnresolvedSuperBinary(
|
| + ast.Send node,
|
| + Element element,
|
| + BinaryOperator operator,
|
| + ast.Node argument,
|
| + _) {
|
| + handleUnresolvedSuperInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + void visitUnresolvedSuperGet(
|
| + ast.Send node,
|
| + Element element,
|
| + _) {
|
| + handleUnresolvedSuperInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + void visitUnresolvedSuperInvoke(
|
| + ast.Send node,
|
| + Element element,
|
| + ast.Node argument,
|
| + Selector selector,
|
| + _) {
|
| + handleUnresolvedSuperInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperFieldGet(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + _) {
|
| + handleSuperGet(node, field);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperGetterGet(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + _) {
|
| + handleSuperGet(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperMethodGet(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + _) {
|
| + handleSuperGet(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperFieldInvoke(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + handleSuperCallInvoke(node, field);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperGetterInvoke(
|
| + ast.Send node,
|
| + MethodElement getter,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + handleSuperCallInvoke(node, getter);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperMethodInvoke(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + handleSuperMethodInvoke(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperIndex(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + ast.Node index,
|
| + _) {
|
| + handleSuperMethodInvoke(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperEquals(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + ast.Node argument,
|
| + _) {
|
| + handleSuperMethodInvoke(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperBinary(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + BinaryOperator operator,
|
| + ast.Node argument,
|
| + _) {
|
| + handleSuperMethodInvoke(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperUnary(
|
| + ast.Send node,
|
| + UnaryOperator operator,
|
| + MethodElement method,
|
| + _) {
|
| + handleSuperMethodInvoke(node, method);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperMethodIncompatibleInvoke(
|
| + ast.Send node,
|
| + MethodElement method,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + Selector selector = elements.getSelector(node);
|
| + List<HInstruction> inputs = <HInstruction>[];
|
| + addGenericSendArgumentsToList(arguments.nodes, inputs);
|
| + generateSuperNoSuchMethodSend(node, selector, inputs);
|
| + }
|
| +
|
| bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
|
| ClassWorld classWorld = compiler.world;
|
| if (classWorld.isUsedAsMixin(cls)) return true;
|
|
|