Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2960)

Unified Diff: lib/src/checker/rules.dart

Issue 1092183003: Handle calls through call methods (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/checker/checker.dart ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/checker/rules.dart
diff --git a/lib/src/checker/rules.dart b/lib/src/checker/rules.dart
index 4d0317c2cbd0533f8c8e0e62f4671ccdd3758c6d..8ea21879318fbaef5bfff6b98984ef1fa72c5342 100644
--- a/lib/src/checker/rules.dart
+++ b/lib/src/checker/rules.dart
@@ -42,6 +42,32 @@ abstract class TypeRules {
DartType getStaticType(Expression expr) => expr.staticType;
+ /// Given a type t, if t is an interface type with a call method
+ /// defined, return the function type for the call method, otherwise
+ /// return null.
+ FunctionType getCallMethodType(DartType t) {
+ if (t is InterfaceType) {
+ ClassElement element = t.element;
+ InheritanceManager manager = new InheritanceManager(element.library);
+ FunctionType callType = manager.lookupMemberType(t, "call");
+ return callType;
+ }
+ return null;
+ }
+
+ /// Given an expression, return its type assuming it is
+ /// in the caller position of a call (that is, accounting
+ /// for the possibility of a call method). Returns null
+ /// if expression is not statically callable.
+ FunctionType getTypeAsCaller(Expression applicand) {
+ var t = getStaticType(applicand);
+ if (t is InterfaceType) {
+ return getCallMethodType(t);
+ }
+ if (t is FunctionType) return t;
+ return null;
+ }
+
DartType elementType(Element e);
bool isDynamic(DartType t);
@@ -185,16 +211,6 @@ class RestrictedRules extends TypeRules {
throw new StateError("Unexpected type");
}
- FunctionType getCallMethodType(DartType t) {
- if (t is InterfaceType) {
- ClassElement element = t.element;
- InheritanceManager manager = new InheritanceManager(element.library);
- FunctionType callType = manager.lookupMemberType(t, "call");
- return callType;
- }
- return null;
- }
-
/// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC
/// checker to determine whether f1 would be a subtype of f2 if the return
/// type of f1 is set to match f2's return type.
@@ -536,12 +552,12 @@ class RestrictedRules extends TypeRules {
/// invocation.
bool isDynamicCall(Expression call) {
if (options.ignoreTypes) return true;
- var t = getStaticType(call);
- // TODO(jmesserly): fix handling of types with `call` methods. These are not
- // FunctionType, but they also aren't dynamic calls.
- if (t.isDynamic || t.isDartCoreFunction || t is! FunctionType) {
- return true;
- }
+ var t = getTypeAsCaller(call);
+ // TODO(leafp): This will currently return true if t is Function
+ // This is probably the most correct thing to do for now, since
+ // this code is also used by the back end. Maybe revisit at some
+ // point?
+ if (t == null) return true;
// Dynamic as the parameter type is treated as bottom. A function with
// a dynamic parameter type requires a dynamic call in general.
// However, as an optimization, if we have an original definition, we know
« no previous file with comments | « lib/src/checker/checker.dart ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698