OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 concrete_types_inferrer; | 5 library concrete_types_inferrer; |
6 | 6 |
7 import 'dart:collection' show | 7 import 'dart:collection' show |
8 Queue, | 8 Queue, |
9 IterableBase; | 9 IterableBase; |
10 | 10 |
11 import '../native/native.dart' as native; | 11 import '../native/native.dart' as native; |
12 import '../closure.dart' show | 12 import '../closure.dart' show |
13 BoxFieldElement; | 13 BoxFieldElement; |
14 import '../compiler.dart' show | 14 import '../compiler.dart' show |
15 Compiler; | 15 Compiler; |
16 import '../dart_types.dart' show | 16 import '../dart_types.dart' show |
17 DartType, | 17 DartType, |
18 TypeKind; | 18 TypeKind; |
19 import '../diagnostics/spannable.dart' show | 19 import '../diagnostics/spannable.dart' show |
20 Spannable; | 20 Spannable; |
21 import '../elements/elements.dart'; | 21 import '../elements/elements.dart'; |
22 import '../tree/tree.dart'; | 22 import '../tree/tree.dart'; |
23 import '../types/types.dart' show | 23 import '../types/types.dart' show |
24 FlatTypeMask, | 24 FlatTypeMask, |
25 TypeMask, | 25 TypeMask, |
26 TypesInferrer, | 26 TypesInferrer, |
27 UnionTypeMask; | 27 UnionTypeMask; |
28 import '../universe/universe.dart'; | 28 import '../universe/selector.dart' show |
| 29 Selector, |
| 30 SelectorKind; |
| 31 import '../universe/side_effects.dart' show |
| 32 SideEffects; |
29 import '../world.dart' show | 33 import '../world.dart' show |
30 ClassWorld; | 34 ClassWorld; |
31 | 35 |
32 import 'inferrer_visitor.dart'; | 36 import 'inferrer_visitor.dart'; |
33 import 'simple_types_inferrer.dart'; | 37 import 'simple_types_inferrer.dart'; |
34 | 38 |
35 /** | 39 /** |
36 * A singleton concrete type. More precisely, a [BaseType] is one of the | 40 * A singleton concrete type. More precisely, a [BaseType] is one of the |
37 * following: | 41 * following: |
38 * | 42 * |
(...skipping 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 @override | 2008 @override |
2005 ConcreteType registerCalledElement(Spannable node, | 2009 ConcreteType registerCalledElement(Spannable node, |
2006 Selector selector, | 2010 Selector selector, |
2007 TypeMask mask, | 2011 TypeMask mask, |
2008 Element caller, | 2012 Element caller, |
2009 Element callee, | 2013 Element callee, |
2010 ArgumentsTypes<ConcreteType> arguments, | 2014 ArgumentsTypes<ConcreteType> arguments, |
2011 SideEffects sideEffects, | 2015 SideEffects sideEffects, |
2012 bool inLoop) { | 2016 bool inLoop) { |
2013 caller = getRealCaller(caller); | 2017 caller = getRealCaller(caller); |
2014 if ((selector == null) || (selector.kind == SelectorKind.CALL)) { | 2018 if ((selector == null) || (selector.isCall)) { |
2015 callee = callee.implementation; | 2019 callee = callee.implementation; |
2016 if (selector != null && selector.name == 'JS') { | 2020 if (selector != null && selector.name == 'JS') { |
2017 return null; | 2021 return null; |
2018 } | 2022 } |
2019 if (callee.isField) { // toplevel closure call | 2023 if (callee.isField) { // toplevel closure call |
2020 getFieldType(selector, callee); // trigger toplevel field analysis | 2024 getFieldType(selector, callee); // trigger toplevel field analysis |
2021 addFieldReader(callee, caller); | 2025 addFieldReader(callee, caller); |
2022 ConcreteType result = emptyConcreteType; | 2026 ConcreteType result = emptyConcreteType; |
2023 for (FunctionElement function in closures.functionElements) { | 2027 for (FunctionElement function in closures.functionElements) { |
2024 addCaller(function, caller); | 2028 addCaller(function, caller); |
(...skipping 12 matching lines...) Expand all Loading... |
2037 if (send.receiver.isSuper()) { | 2041 if (send.receiver.isSuper()) { |
2038 receiverClass = | 2042 receiverClass = |
2039 currentWorkItem.environment.classOfThis.superclass; | 2043 currentWorkItem.environment.classOfThis.superclass; |
2040 } else { | 2044 } else { |
2041 receiverClass = currentWorkItem.environment.classOfThis; | 2045 receiverClass = currentWorkItem.environment.classOfThis; |
2042 } | 2046 } |
2043 } | 2047 } |
2044 } | 2048 } |
2045 return getSendReturnType(selector, callee, receiverClass, arguments); | 2049 return getSendReturnType(selector, callee, receiverClass, arguments); |
2046 } | 2050 } |
2047 } else if (selector.kind == SelectorKind.GETTER) { | 2051 } else if (selector.isGetter) { |
2048 if (callee.isField) { | 2052 if (callee.isField) { |
2049 addFieldReader(callee, caller); | 2053 addFieldReader(callee, caller); |
2050 return getFieldType(selector, callee); | 2054 return getFieldType(selector, callee); |
2051 } else if (callee.isGetter) { | 2055 } else if (callee.isGetter) { |
2052 Element enclosing = callee.enclosingElement.isCompilationUnit | 2056 Element enclosing = callee.enclosingElement.isCompilationUnit |
2053 ? null : callee.enclosingElement; | 2057 ? null : callee.enclosingElement; |
2054 addCaller(callee, caller); | 2058 addCaller(callee, caller); |
2055 ArgumentsTypes noArguments = new ArgumentsTypes([], new Map()); | 2059 ArgumentsTypes noArguments = new ArgumentsTypes([], new Map()); |
2056 return getSendReturnType(selector, callee, enclosing, noArguments); | 2060 return getSendReturnType(selector, callee, enclosing, noArguments); |
2057 } else if (callee.isFunction) { | 2061 } else if (callee.isFunction) { |
2058 addClosure(callee, null, null); | 2062 addClosure(callee, null, null); |
2059 return singletonConcreteType(baseTypes.functionBaseType); | 2063 return singletonConcreteType(baseTypes.functionBaseType); |
2060 } | 2064 } |
2061 } else if (selector.kind == SelectorKind.SETTER) { | 2065 } else if (selector.isSetter) { |
2062 ConcreteType argumentType = arguments.positional.first; | 2066 ConcreteType argumentType = arguments.positional.first; |
2063 if (callee.isField) { | 2067 if (callee.isField) { |
2064 augmentFieldType(callee, argumentType); | 2068 augmentFieldType(callee, argumentType); |
2065 } else if (callee.isSetter) { | 2069 } else if (callee.isSetter) { |
2066 FunctionElement setter = callee; | 2070 FunctionElement setter = callee; |
2067 // TODO(polux): A setter always returns void so there's no need to | 2071 // TODO(polux): A setter always returns void so there's no need to |
2068 // invalidate its callers even if it is called with new arguments. | 2072 // invalidate its callers even if it is called with new arguments. |
2069 // However, if we start to record more than returned types, like | 2073 // However, if we start to record more than returned types, like |
2070 // exceptions for instance, we need to do it by uncommenting the | 2074 // exceptions for instance, we need to do it by uncommenting the |
2071 // following line. | 2075 // following line. |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 ConcreteType handleLocalGet(Send node, LocalElement local) { | 2388 ConcreteType handleLocalGet(Send node, LocalElement local) { |
2385 if (inferrer.testMode) { | 2389 if (inferrer.testMode) { |
2386 ConcreteType type = locals.use(local); | 2390 ConcreteType type = locals.use(local); |
2387 if (type != null) { | 2391 if (type != null) { |
2388 inferrer.augmentInferredType(node, type); | 2392 inferrer.augmentInferredType(node, type); |
2389 } | 2393 } |
2390 } | 2394 } |
2391 return super.handleLocalGet(node, local); | 2395 return super.handleLocalGet(node, local); |
2392 } | 2396 } |
2393 } | 2397 } |
OLD | NEW |