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 dart_types; | 5 library dart_types; |
6 | 6 |
7 import 'dart:math' show min; | 7 import 'dart:math' show min; |
8 | 8 |
9 import 'dart2jslib.dart' show Compiler, invariant, Script, Message; | 9 import 'dart2jslib.dart' show Compiler, invariant, Script, Message; |
10 import 'elements/modelx.dart' | 10 import 'elements/modelx.dart' |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 * The notation is known from this lambda calculus rule: | 53 * The notation is known from this lambda calculus rule: |
54 * | 54 * |
55 * (lambda x.e0)e1 -> [e1/x]e0. | 55 * (lambda x.e0)e1 -> [e1/x]e0. |
56 * | 56 * |
57 * See [TypeVariableType] for a motivation for this method. | 57 * See [TypeVariableType] for a motivation for this method. |
58 * | 58 * |
59 * Invariant: There must be the same number of [arguments] and [parameters]. | 59 * Invariant: There must be the same number of [arguments] and [parameters]. |
60 */ | 60 */ |
61 DartType subst(Link<DartType> arguments, Link<DartType> parameters); | 61 DartType subst(Link<DartType> arguments, Link<DartType> parameters); |
62 | 62 |
| 63 /// Performs the substitution of the type arguments of [type] for their |
| 64 /// corresponding type variables in this type. |
| 65 DartType substByContext(GenericType type) => |
| 66 subst(type.typeArguments, type.element.typeVariables); |
| 67 |
63 /** | 68 /** |
64 * Returns the unaliased type of this type. | 69 * Returns the unaliased type of this type. |
65 * | 70 * |
66 * The unaliased type of a typedef'd type is the unaliased type to which its | 71 * The unaliased type of a typedef'd type is the unaliased type to which its |
67 * name is bound. The unaliased version of any other type is the type itself. | 72 * name is bound. The unaliased version of any other type is the type itself. |
68 * | 73 * |
69 * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the | 74 * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the |
70 * function type [: (B) -> A :] and the unaliased type of | 75 * function type [: (B) -> A :] and the unaliased type of |
71 * [: Func<int,String> :] is the function type [: (String) -> int :]. | 76 * [: Func<int,String> :] is the function type [: (String) -> int :]. |
72 */ | 77 */ |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 795 |
791 TypeKind get kind => TypeKind.TYPEDEF; | 796 TypeKind get kind => TypeKind.TYPEDEF; |
792 | 797 |
793 String get name => element.name; | 798 String get name => element.name; |
794 | 799 |
795 DartType unalias(Compiler compiler) { | 800 DartType unalias(Compiler compiler) { |
796 // TODO(ahe): This should be [ensureResolved]. | 801 // TODO(ahe): This should be [ensureResolved]. |
797 compiler.resolveTypedef(element); | 802 compiler.resolveTypedef(element); |
798 element.checkCyclicReference(compiler); | 803 element.checkCyclicReference(compiler); |
799 DartType definition = element.alias.unalias(compiler); | 804 DartType definition = element.alias.unalias(compiler); |
800 TypedefType declaration = element.computeType(compiler); | 805 return definition.substByContext(this); |
801 return definition.subst(typeArguments, declaration.typeArguments); | |
802 } | 806 } |
803 | 807 |
804 int get hashCode => super.hashCode; | 808 int get hashCode => super.hashCode; |
805 | 809 |
806 TypedefType asRaw() => super.asRaw(); | 810 TypedefType asRaw() => super.asRaw(); |
807 | 811 |
808 accept(DartTypeVisitor visitor, var argument) { | 812 accept(DartTypeVisitor visitor, var argument) { |
809 return visitor.visitTypedefType(this, argument); | 813 return visitor.visitTypedefType(this, argument); |
810 } | 814 } |
811 } | 815 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 // TODO(johnniwinther): Add check of assignment to field with no | 886 // TODO(johnniwinther): Add check of assignment to field with no |
883 // setter. | 887 // setter. |
884 FunctionType functionType = | 888 FunctionType functionType = |
885 abstractFieldElement.getter.computeType(compiler); | 889 abstractFieldElement.getter.computeType(compiler); |
886 type = functionType.returnType; | 890 type = functionType.returnType; |
887 } | 891 } |
888 } else { | 892 } else { |
889 type = element.computeType(compiler); | 893 type = element.computeType(compiler); |
890 } | 894 } |
891 if (!declarer.element.typeVariables.isEmpty) { | 895 if (!declarer.element.typeVariables.isEmpty) { |
892 type = type.subst(declarer.typeArguments, | 896 type = type.substByContext(declarer); |
893 declarer.element.typeVariables); | 897 type = type.substByContext(receiver); |
894 type = type.subst(receiver.typeArguments, | |
895 receiver.element.typeVariables); | |
896 } | 898 } |
897 cachedType = type; | 899 cachedType = type; |
898 } | 900 } |
899 return cachedType; | 901 return cachedType; |
900 } | 902 } |
901 | 903 |
902 String toString() { | 904 String toString() { |
903 return '$receiver.${element.name}'; | 905 return '$receiver.${element.name}'; |
904 } | 906 } |
905 } | 907 } |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 * declared on [element]. Calls [checkTypeVariableBound] on each type | 1300 * declared on [element]. Calls [checkTypeVariableBound] on each type |
1299 * argument and bound. | 1301 * argument and bound. |
1300 */ | 1302 */ |
1301 void checkTypeVariableBounds(GenericType type, | 1303 void checkTypeVariableBounds(GenericType type, |
1302 CheckTypeVariableBound checkTypeVariableBound) { | 1304 CheckTypeVariableBound checkTypeVariableBound) { |
1303 TypeDeclarationElement element = type.element; | 1305 TypeDeclarationElement element = type.element; |
1304 Link<DartType> typeArguments = type.typeArguments; | 1306 Link<DartType> typeArguments = type.typeArguments; |
1305 Link<DartType> typeVariables = element.typeVariables; | 1307 Link<DartType> typeVariables = element.typeVariables; |
1306 while (!typeVariables.isEmpty && !typeArguments.isEmpty) { | 1308 while (!typeVariables.isEmpty && !typeArguments.isEmpty) { |
1307 TypeVariableType typeVariable = typeVariables.head; | 1309 TypeVariableType typeVariable = typeVariables.head; |
1308 DartType bound = typeVariable.element.bound.subst( | 1310 DartType bound = typeVariable.element.bound.substByContext(type); |
1309 type.typeArguments, element.typeVariables); | |
1310 DartType typeArgument = typeArguments.head; | 1311 DartType typeArgument = typeArguments.head; |
1311 checkTypeVariableBound(type, typeArgument, typeVariable, bound); | 1312 checkTypeVariableBound(type, typeArgument, typeVariable, bound); |
1312 typeVariables = typeVariables.tail; | 1313 typeVariables = typeVariables.tail; |
1313 typeArguments = typeArguments.tail; | 1314 typeArguments = typeArguments.tail; |
1314 } | 1315 } |
1315 assert(typeVariables.isEmpty && typeArguments.isEmpty); | 1316 assert(typeVariables.isEmpty && typeArguments.isEmpty); |
1316 } | 1317 } |
1317 | 1318 |
1318 /** | 1319 /** |
1319 * Helper method for performing substitution of a linked list of types. | 1320 * Helper method for performing substitution of a linked list of types. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 static List<DartType> sorted(Iterable<DartType> types) { | 1495 static List<DartType> sorted(Iterable<DartType> types) { |
1495 return types.toList()..sort(compare); | 1496 return types.toList()..sort(compare); |
1496 } | 1497 } |
1497 | 1498 |
1498 /// Computes the least upper bound of two interface types [a] and [b]. | 1499 /// Computes the least upper bound of two interface types [a] and [b]. |
1499 InterfaceType computeLeastUpperBoundInterfaces(InterfaceType a, | 1500 InterfaceType computeLeastUpperBoundInterfaces(InterfaceType a, |
1500 InterfaceType b) { | 1501 InterfaceType b) { |
1501 | 1502 |
1502 /// Returns the set of supertypes of [type] at depth [depth]. | 1503 /// Returns the set of supertypes of [type] at depth [depth]. |
1503 Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) { | 1504 Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) { |
1504 ClassElement cls = type.element; | 1505 OrderedTypeSet types = type.element.allSupertypesAndSelf; |
1505 OrderedTypeSet types = cls.allSupertypesAndSelf; | |
1506 Link<DartType> typeVariables = cls.typeVariables; | |
1507 Link<DartType> typeArguments = type.typeArguments; | |
1508 Set<DartType> set = new Set<DartType>(); | 1506 Set<DartType> set = new Set<DartType>(); |
1509 types.forEach(depth, (DartType type) { | 1507 types.forEach(depth, (DartType supertype) { |
1510 set.add(type.subst(typeArguments, typeVariables)); | 1508 set.add(supertype.substByContext(type)); |
1511 }); | 1509 }); |
1512 return set; | 1510 return set; |
1513 } | 1511 } |
1514 | 1512 |
1515 ClassElement aClass = a.element; | 1513 ClassElement aClass = a.element; |
1516 ClassElement bClass = b.element; | 1514 ClassElement bClass = b.element; |
1517 int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth); | 1515 int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth); |
1518 for (int depth = maxCommonDepth; depth >= 0; depth--) { | 1516 for (int depth = maxCommonDepth; depth >= 0; depth--) { |
1519 Set<DartType> aTypeSet = getSupertypesAtDepth(a, depth); | 1517 Set<DartType> aTypeSet = getSupertypesAtDepth(a, depth); |
1520 Set<DartType> bTypeSet = getSupertypesAtDepth(b, depth); | 1518 Set<DartType> bTypeSet = getSupertypesAtDepth(b, depth); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 } | 1751 } |
1754 | 1752 |
1755 bool visitGenericType(GenericType type, DartType argument) { | 1753 bool visitGenericType(GenericType type, DartType argument) { |
1756 if (argument is GenericType) { | 1754 if (argument is GenericType) { |
1757 if (type.element != argument.element) return false; | 1755 if (type.element != argument.element) return false; |
1758 return visitTypes(type.typeArguments, argument.typeArguments); | 1756 return visitTypes(type.typeArguments, argument.typeArguments); |
1759 } | 1757 } |
1760 return false; | 1758 return false; |
1761 } | 1759 } |
1762 } | 1760 } |
OLD | NEW |