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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « lib/src/checker/checker.dart ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dev_compiler.src.checker.rules; 5 library dev_compiler.src.checker.rules;
6 6
7 import 'package:analyzer/src/generated/ast.dart'; 7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/resolver.dart'; 9 import 'package:analyzer/src/generated/resolver.dart';
10 10
(...skipping 24 matching lines...) Expand all
35 bool isIntType(DartType t) => t == provider.intType; 35 bool isIntType(DartType t) => t == provider.intType;
36 bool isNumType(DartType t) => t == provider.intType.superclass; 36 bool isNumType(DartType t) => t == provider.intType.superclass;
37 bool isStringType(DartType t) => t == provider.stringType; 37 bool isStringType(DartType t) => t == provider.stringType;
38 bool isNonNullableType(DartType t) => false; 38 bool isNonNullableType(DartType t) => false;
39 bool maybeNonNullableType(DartType t) => false; 39 bool maybeNonNullableType(DartType t) => false;
40 40
41 StaticInfo checkAssignment(Expression expr, DartType t, bool constContext); 41 StaticInfo checkAssignment(Expression expr, DartType t, bool constContext);
42 42
43 DartType getStaticType(Expression expr) => expr.staticType; 43 DartType getStaticType(Expression expr) => expr.staticType;
44 44
45 /// Given a type t, if t is an interface type with a call method
46 /// defined, return the function type for the call method, otherwise
47 /// return null.
48 FunctionType getCallMethodType(DartType t) {
49 if (t is InterfaceType) {
50 ClassElement element = t.element;
51 InheritanceManager manager = new InheritanceManager(element.library);
52 FunctionType callType = manager.lookupMemberType(t, "call");
53 return callType;
54 }
55 return null;
56 }
57
58 /// Given an expression, return its type assuming it is
59 /// in the caller position of a call (that is, accounting
60 /// for the possibility of a call method). Returns null
61 /// if expression is not statically callable.
62 FunctionType getTypeAsCaller(Expression applicand) {
63 var t = getStaticType(applicand);
64 if (t is InterfaceType) {
65 return getCallMethodType(t);
66 }
67 if (t is FunctionType) return t;
68 return null;
69 }
70
45 DartType elementType(Element e); 71 DartType elementType(Element e);
46 72
47 bool isDynamic(DartType t); 73 bool isDynamic(DartType t);
48 bool isDynamicTarget(Expression expr); 74 bool isDynamicTarget(Expression expr);
49 bool isDynamicCall(Expression call); 75 bool isDynamicCall(Expression call);
50 } 76 }
51 77
52 class DartRules extends TypeRules { 78 class DartRules extends TypeRules {
53 DartRules(TypeProvider provider) : super(provider); 79 DartRules(TypeProvider provider) : super(provider);
54 80
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 var typeArguments = t.typeArguments; 204 var typeArguments = t.typeArguments;
179 for (var typeArgument in typeArguments) { 205 for (var typeArgument in typeArguments) {
180 if (!_isTop(typeArgument)) return false; 206 if (!_isTop(typeArgument)) return false;
181 } 207 }
182 return true; 208 return true;
183 } 209 }
184 210
185 throw new StateError("Unexpected type"); 211 throw new StateError("Unexpected type");
186 } 212 }
187 213
188 FunctionType getCallMethodType(DartType t) {
189 if (t is InterfaceType) {
190 ClassElement element = t.element;
191 InheritanceManager manager = new InheritanceManager(element.library);
192 FunctionType callType = manager.lookupMemberType(t, "call");
193 return callType;
194 }
195 return null;
196 }
197
198 /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC 214 /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC
199 /// checker to determine whether f1 would be a subtype of f2 if the return 215 /// checker to determine whether f1 would be a subtype of f2 if the return
200 /// type of f1 is set to match f2's return type. 216 /// type of f1 is set to match f2's return type.
201 // [fuzzyArrows] indicates whether or not the f1 and f2 should be 217 // [fuzzyArrows] indicates whether or not the f1 and f2 should be
202 // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as 218 // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as
203 // bottom). 219 // bottom).
204 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, 220 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2,
205 {bool fuzzyArrows: true, bool ignoreReturn: false}) { 221 {bool fuzzyArrows: true, bool ignoreReturn: false}) {
206 final r1s = f1.normalParameterTypes; 222 final r1s = f1.normalParameterTypes;
207 final o1s = f1.optionalParameterTypes; 223 final o1s = f1.optionalParameterTypes;
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic; 545 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic;
530 546
531 /// Returns `true` if the target expression is dynamic. 547 /// Returns `true` if the target expression is dynamic.
532 bool isDynamicTarget(Expression target) => 548 bool isDynamicTarget(Expression target) =>
533 options.ignoreTypes || utils.isDynamicTarget(target); 549 options.ignoreTypes || utils.isDynamicTarget(target);
534 550
535 /// Returns `true` if the expression is a dynamic function call or method 551 /// Returns `true` if the expression is a dynamic function call or method
536 /// invocation. 552 /// invocation.
537 bool isDynamicCall(Expression call) { 553 bool isDynamicCall(Expression call) {
538 if (options.ignoreTypes) return true; 554 if (options.ignoreTypes) return true;
539 var t = getStaticType(call); 555 var t = getTypeAsCaller(call);
540 // TODO(jmesserly): fix handling of types with `call` methods. These are not 556 // TODO(leafp): This will currently return true if t is Function
541 // FunctionType, but they also aren't dynamic calls. 557 // This is probably the most correct thing to do for now, since
542 if (t.isDynamic || t.isDartCoreFunction || t is! FunctionType) { 558 // this code is also used by the back end. Maybe revisit at some
543 return true; 559 // point?
544 } 560 if (t == null) return true;
545 // Dynamic as the parameter type is treated as bottom. A function with 561 // Dynamic as the parameter type is treated as bottom. A function with
546 // a dynamic parameter type requires a dynamic call in general. 562 // a dynamic parameter type requires a dynamic call in general.
547 // However, as an optimization, if we have an original definition, we know 563 // However, as an optimization, if we have an original definition, we know
548 // dynamic is reified as Object - in this case a regular call is fine. 564 // dynamic is reified as Object - in this case a regular call is fine.
549 if (call is SimpleIdentifier) { 565 if (call is SimpleIdentifier) {
550 var element = call.staticElement; 566 var element = call.staticElement;
551 if (element is FunctionElement || element is MethodElement) { 567 if (element is FunctionElement || element is MethodElement) {
552 // An original declaration. 568 // An original declaration.
553 return false; 569 return false;
554 } 570 }
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 var entries = e.entries; 839 var entries = e.entries;
824 bool inferEntry(MapLiteralEntry entry) { 840 bool inferEntry(MapLiteralEntry entry) {
825 return _inferExpression(entry.key, kType, errors) && 841 return _inferExpression(entry.key, kType, errors) &&
826 _inferExpression(entry.value, vType, errors); 842 _inferExpression(entry.value, vType, errors);
827 } 843 }
828 var b = entries.every(inferEntry); 844 var b = entries.every(inferEntry);
829 if (b) annotateMapLiteral(e, targs); 845 if (b) annotateMapLiteral(e, targs);
830 return b; 846 return b;
831 } 847 }
832 } 848 }
OLDNEW
« 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