OLD | NEW |
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 analyzer.src.generated.type_system; | 5 library analyzer.src.generated.type_system; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
9 | 9 |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
11 import 'package:analyzer/dart/element/type.dart'; | 11 import 'package:analyzer/dart/element/type.dart'; |
12 import 'package:analyzer/src/dart/element/element.dart'; | 12 import 'package:analyzer/src/dart/element/element.dart'; |
13 import 'package:analyzer/src/dart/element/type.dart'; | 13 import 'package:analyzer/src/dart/element/type.dart'; |
14 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 14 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
15 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 15 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
16 import 'package:analyzer/src/generated/utilities_dart.dart'; | 16 import 'package:analyzer/src/generated/utilities_dart.dart'; |
17 | 17 |
18 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited); | 18 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited); |
19 | 19 |
20 /** | 20 /** |
21 * Implementation of [TypeSystem] using the strong mode rules. | 21 * Implementation of [TypeSystem] using the strong mode rules. |
22 * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md | 22 * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md |
23 */ | 23 */ |
24 class StrongTypeSystemImpl extends TypeSystem { | 24 class StrongTypeSystemImpl extends TypeSystem { |
25 final _specTypeSystem = new TypeSystemImpl(); | 25 final _specTypeSystem = new TypeSystemImpl(); |
26 | 26 |
27 StrongTypeSystemImpl(); | |
28 | |
29 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { | 27 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { |
30 return ft.parameters.any((p) => predicate(p.type)); | 28 return ft.parameters.any((p) => predicate(p.type)); |
31 } | 29 } |
32 | 30 |
33 @override | 31 @override |
34 bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from); | 32 bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from); |
35 | 33 |
36 /** | 34 /** |
37 * Given a type t, if t is an interface type with a call method | 35 * Given a type t, if t is an interface type with a call method |
38 * defined, return the function type for the call method, otherwise | 36 * defined, return the function type for the call method, otherwise |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 */ | 500 */ |
503 bool isMoreSpecificThan(DartType leftType, DartType rightType); | 501 bool isMoreSpecificThan(DartType leftType, DartType rightType); |
504 | 502 |
505 /** | 503 /** |
506 * Return `true` if the [leftType] is a subtype of the [rightType] (that is, | 504 * Return `true` if the [leftType] is a subtype of the [rightType] (that is, |
507 * if leftType <: rightType). | 505 * if leftType <: rightType). |
508 */ | 506 */ |
509 bool isSubtypeOf(DartType leftType, DartType rightType); | 507 bool isSubtypeOf(DartType leftType, DartType rightType); |
510 | 508 |
511 /** | 509 /** |
| 510 * Searches the superinterfaces of [type] for implementations of [genericType] |
| 511 * and returns the most specific type argument used for that generic type. |
| 512 * |
| 513 * For example, given [type] `List<int>` and [genericType] `Iterable<T>`, |
| 514 * returns [int]. |
| 515 * |
| 516 * Returns `null` if [type] does not implement [genericType]. |
| 517 */ |
| 518 // TODO(jmesserly): this is very similar to code used for flattening futures. |
| 519 // The only difference is, because of a lack of TypeProvider, the other method |
| 520 // has to match the Future type by its name and library. Here was are passed |
| 521 // in the correct type. |
| 522 DartType mostSpecificTypeArgument(DartType type, DartType genericType) { |
| 523 if (type is! InterfaceType) return null; |
| 524 |
| 525 // Walk the superinterface hierarchy looking for [genericType]. |
| 526 List<DartType> candidates = <DartType>[]; |
| 527 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); |
| 528 void recurse(InterfaceTypeImpl interface) { |
| 529 if (interface.element == genericType.element && |
| 530 interface.typeArguments.isNotEmpty) { |
| 531 candidates.add(interface.typeArguments[0]); |
| 532 } |
| 533 if (visitedClasses.add(interface.element)) { |
| 534 if (interface.superclass != null) { |
| 535 recurse(interface.superclass); |
| 536 } |
| 537 interface.mixins.forEach(recurse); |
| 538 interface.interfaces.forEach(recurse); |
| 539 visitedClasses.remove(interface.element); |
| 540 } |
| 541 } |
| 542 |
| 543 recurse(type); |
| 544 |
| 545 // Since the interface may be implemented multiple times with different |
| 546 // type arguments, choose the best one. |
| 547 return InterfaceTypeImpl.findMostSpecificType(candidates, this); |
| 548 } |
| 549 |
| 550 /** |
512 * Given a [DartType] type, return the [TypeParameterElement]s corresponding | 551 * Given a [DartType] type, return the [TypeParameterElement]s corresponding |
513 * to its formal type parameters (if any). | 552 * to its formal type parameters (if any). |
514 * | 553 * |
515 * @param type the type whose type arguments are to be returned | 554 * @param type the type whose type arguments are to be returned |
516 * @return the type arguments associated with the given type | 555 * @return the type arguments associated with the given type |
517 */ | 556 */ |
518 List<TypeParameterElement> typeFormalsAsElements(DartType type) { | 557 List<TypeParameterElement> typeFormalsAsElements(DartType type) { |
519 if (type is FunctionType) { | 558 if (type is FunctionType) { |
520 return type.typeFormals; | 559 return type.typeFormals; |
521 } else if (type is InterfaceType) { | 560 } else if (type is InterfaceType) { |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 } else { | 990 } else { |
952 passedOut = true; | 991 passedOut = true; |
953 } | 992 } |
954 } else if (type is FunctionType) { | 993 } else if (type is FunctionType) { |
955 _visitFunctionType(typeParam, type, paramIn); | 994 _visitFunctionType(typeParam, type, paramIn); |
956 } else if (type is InterfaceType) { | 995 } else if (type is InterfaceType) { |
957 _visitInterfaceType(typeParam, type, paramIn); | 996 _visitInterfaceType(typeParam, type, paramIn); |
958 } | 997 } |
959 } | 998 } |
960 } | 999 } |
OLD | NEW |