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 d4ddcd5b8bf7e359f1277d1ed8b2250d724eb843..ebda6b57b47e04bca3d9e24dc76adb16b3f89d51 100644 |
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
@@ -5,24 +5,26 @@ |
library simple_types_inferrer; |
import '../closure.dart' show ClosureClassMap, ClosureScope; |
+import '../cps_ir/cps_ir_nodes.dart' as cps_ir show Node; |
import '../dart_types.dart' |
show DartType, InterfaceType, FunctionType, TypeKind; |
import '../elements/elements.dart'; |
import '../js_backend/js_backend.dart' as js; |
import '../native/native.dart' as native; |
+import '../resolution/operators.dart' as op; |
import '../tree/tree.dart' as ast; |
-import '../cps_ir/cps_ir_nodes.dart' as cps_ir show Node; |
-import '../util/util.dart' show Link, Spannable, Setlet; |
import '../types/types.dart' |
show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask, |
ElementTypeMask, ValueTypeMask, TypeSystem, MinimalInferrerEngine; |
+import '../util/util.dart' show Link, Spannable, Setlet; |
import 'inferrer_visitor.dart'; |
// BUG(8802): There's a bug in the analyzer that makes the re-export |
// of Selector from dart2jslib.dart fail. For now, we work around that |
// by importing universe.dart explicitly and disabling the re-export. |
import '../dart2jslib.dart' hide Selector, TypedSelector; |
-import '../universe/universe.dart' show Selector, SideEffects, TypedSelector; |
+import '../universe/universe.dart' |
+ show Selector, SideEffects, TypedSelector, CallStructure; |
/** |
* An implementation of [TypeSystem] for [TypeMask]. |
@@ -967,37 +969,219 @@ class SimpleTypeInferrerVisitor<T> |
return rhsType; |
} |
- T handleSuperConstructorInvoke(ast.Send node) { |
- return visitSuperSend(node); |
- } |
- |
- T visitSuperSend(ast.Send node) { |
- Element element = elements[node]; |
+ /// Handle a super access or invocation that results in a `noSuchMethod` call. |
+ T handleErroneousSuperSend(ast.Send node) { |
ArgumentsTypes arguments = node.isPropertyAccess |
? null |
: analyzeArguments(node.arguments); |
- if (visitingInitializers) { |
- seenSuperConstructorCall = true; |
- analyzeSuperConstructorCall(element, arguments); |
- } |
Selector selector = elements.getSelector(node); |
- // TODO(ngeoffray): We could do better here if we knew what we |
+ // TODO(herhut): We could do better here if we knew what we |
// are calling does not expose this. |
isThisExposed = true; |
- if (Elements.isUnresolved(element) |
- || !selector.applies(element, compiler.world)) { |
- // Ensure we create a node, to make explicit the call to the |
- // `noSuchMethod` handler. |
- return handleDynamicSend(node, selector, superType, arguments); |
- } else if (node.isPropertyAccess |
- || element.isFunction |
- || element.isGenerativeConstructor) { |
- return handleStaticSend(node, selector, element, arguments); |
- } else { |
- return inferrer.registerCalledClosure( |
- node, selector, inferrer.typeOfElement(element), |
- outermostElement, arguments, sideEffects, inLoop); |
- } |
+ // Ensure we create a node, to make explicit the call to the |
+ // `noSuchMethod` handler. |
+ return handleDynamicSend(node, selector, superType, arguments); |
+ } |
+ |
+ /// Handle a .call invocation on the values retrieved from the super |
+ /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. |
+ T handleSuperClosureCall( |
+ ast.Send node, |
+ Element element, |
+ ast.NodeList arguments) { |
+ ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); |
+ Selector selector = elements.getSelector(node); |
+ // TODO(herhut): We could do better here if we knew what we |
+ // are calling does not expose this. |
+ isThisExposed = true; |
+ return inferrer.registerCalledClosure( |
+ node, selector, inferrer.typeOfElement(element), |
+ outermostElement, argumentTypes, sideEffects, inLoop); |
+ } |
+ |
+ /// Handle an invocation of super [method]. |
+ T handleSuperMethodInvoke(ast.Send node, |
+ MethodElement method, |
+ ArgumentsTypes arguments) { |
+ // TODO(herhut): We could do better here if we knew what we |
+ // are calling does not expose this. |
+ isThisExposed = true; |
+ return handleStaticSend( |
+ node, elements.getSelector(node), method, arguments); |
+ } |
+ |
+ /// Handle access to a super field or getter [element]. |
+ T handleSuperGet(ast.Send node, |
+ Element element) { |
+ // TODO(herhut): We could do better here if we knew what we |
+ // are calling does not expose this. |
+ isThisExposed = true; |
+ return handleStaticSend( |
+ node, elements.getSelector(node), element, null); |
+ } |
+ |
+ /// Handle super constructor invocation. |
+ @override |
+ T handleSuperConstructorInvoke(ast.Send node) { |
+ Element element = elements[node]; |
+ ArgumentsTypes arguments = analyzeArguments(node.arguments); |
+ assert(visitingInitializers); |
+ seenSuperConstructorCall = true; |
+ analyzeSuperConstructorCall(element, arguments); |
+ return handleStaticSend( |
+ node, elements.getSelector(node), element, arguments); |
+ } |
+ |
+ @override |
+ T visitUnresolvedSuperIndex( |
+ ast.Send node, |
+ Element element, |
+ ast.Node index, |
+ _) { |
+ return handleErroneousSuperSend(node); |
+ } |
+ |
+ @override |
+ T visitUnresolvedSuperUnary( |
+ ast.Send node, |
+ op.UnaryOperator operator, |
+ Element element, |
+ _) { |
+ return handleErroneousSuperSend(node); |
+ } |
+ |
+ @override |
+ T visitUnresolvedSuperBinary( |
+ ast.Send node, |
+ Element element, |
+ op.BinaryOperator operator, |
+ ast.Node argument, |
+ _) { |
+ return handleErroneousSuperSend(node); |
+ } |
+ |
+ @override |
+ T visitUnresolvedSuperGet( |
+ ast.Send node, |
+ Element element, |
+ _) { |
+ return handleErroneousSuperSend(node); |
+ } |
+ |
+ @override |
+ T visitUnresolvedSuperInvoke( |
+ ast.Send node, |
+ Element element, |
+ ast.Node argument, |
+ Selector selector, |
+ _) { |
+ return handleErroneousSuperSend(node); |
+ } |
+ |
+ @override |
+ T visitSuperFieldGet( |
+ ast.Send node, |
+ FieldElement field, |
+ _) { |
+ return handleSuperGet(node, field); |
+ } |
+ |
+ @override |
+ T visitSuperGetterGet( |
+ ast.Send node, |
+ MethodElement method, |
+ _) { |
+ return handleSuperGet(node, method); |
+ } |
+ |
+ @override |
+ T visitSuperMethodGet( |
+ ast.Send node, |
+ MethodElement method, |
+ _) { |
+ return handleSuperGet(node, method); |
+ } |
+ |
+ @override |
+ T visitSuperFieldInvoke( |
+ ast.Send node, |
+ FieldElement field, |
+ ast.NodeList arguments, |
+ CallStructure callStructure, |
+ _) { |
+ return handleSuperClosureCall(node, field, arguments); |
+ } |
+ |
+ @override |
+ T visitSuperGetterInvoke( |
+ ast.Send node, |
+ MethodElement getter, |
+ ast.NodeList arguments, |
+ CallStructure callStructure, |
+ _) { |
+ return handleSuperClosureCall(node, getter, arguments); |
+ } |
+ |
+ @override |
+ T visitSuperMethodInvoke( |
+ ast.Send node, |
+ MethodElement method, |
+ ast.NodeList arguments, |
+ CallStructure callStructure, |
+ _) { |
+ return handleSuperMethodInvoke( |
+ node, method, analyzeArguments(arguments.nodes)); |
+ } |
+ |
+ @override |
+ T visitSuperIndex( |
+ ast.Send node, |
+ MethodElement method, |
+ ast.Node index, |
+ _) { |
+ return handleSuperMethodInvoke( |
+ node, method, analyzeArguments(node.arguments)); |
+ } |
+ |
+ @override |
+ T visitSuperEquals( |
+ ast.Send node, |
+ MethodElement method, |
+ ast.Node argument, |
+ _) { |
+ return handleSuperMethodInvoke( |
+ node, method, analyzeArguments(node.arguments)); |
+ } |
+ |
+ @override |
+ T visitSuperBinary( |
+ ast.Send node, |
+ MethodElement method, |
+ op.BinaryOperator operator, |
+ ast.Node argument, |
+ _) { |
+ return handleSuperMethodInvoke( |
+ node, method, analyzeArguments(node.arguments)); |
+ } |
+ |
+ @override |
+ T visitSuperUnary( |
+ ast.Send node, |
+ op.UnaryOperator operator, |
+ MethodElement method, |
+ _) { |
+ return handleSuperMethodInvoke( |
+ node, method, analyzeArguments(node.arguments)); |
+ } |
+ |
+ @override |
+ T visitSuperMethodIncompatibleInvoke( |
+ ast.Send node, |
+ MethodElement method, |
+ ast.NodeList arguments, |
+ CallStructure callStructure, |
+ _) { |
+ return handleErroneousSuperSend(node); |
} |
// Try to find the length given to a fixed array constructor call. |