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 'dart2jslib.dart' show Compiler, invariant, Script, Message; | 7 import 'dart2jslib.dart' show Compiler, invariant, Script, Message; |
8 import 'elements/modelx.dart' | 8 import 'elements/modelx.dart' |
9 show VoidElementX, LibraryElementX, BaseClassElementX; | 9 show VoidElementX, LibraryElementX, BaseClassElementX; |
10 import 'elements/elements.dart'; | 10 import 'elements/elements.dart'; |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 } | 901 } |
902 return cachedType; | 902 return cachedType; |
903 } | 903 } |
904 | 904 |
905 String toString() { | 905 String toString() { |
906 return '$receiver.${element.name.slowToString()}'; | 906 return '$receiver.${element.name.slowToString()}'; |
907 } | 907 } |
908 } | 908 } |
909 | 909 |
910 abstract class DartTypeVisitor<R, A> { | 910 abstract class DartTypeVisitor<R, A> { |
| 911 const DartTypeVisitor(); |
| 912 |
911 R visitType(DartType type, A argument); | 913 R visitType(DartType type, A argument); |
912 | 914 |
913 R visitVoidType(VoidType type, A argument) => | 915 R visitVoidType(VoidType type, A argument) => |
914 visitType(type, argument); | 916 visitType(type, argument); |
915 | 917 |
916 R visitTypeVariableType(TypeVariableType type, A argument) => | 918 R visitTypeVariableType(TypeVariableType type, A argument) => |
917 visitType(type, argument); | 919 visitType(type, argument); |
918 | 920 |
919 R visitFunctionType(FunctionType type, A argument) => | 921 R visitFunctionType(FunctionType type, A argument) => |
920 visitType(type, argument); | 922 visitType(type, argument); |
(...skipping 10 matching lines...) Expand all Loading... |
931 R visitInterfaceType(InterfaceType type, A argument) => | 933 R visitInterfaceType(InterfaceType type, A argument) => |
932 visitGenericType(type, argument); | 934 visitGenericType(type, argument); |
933 | 935 |
934 R visitTypedefType(TypedefType type, A argument) => | 936 R visitTypedefType(TypedefType type, A argument) => |
935 visitGenericType(type, argument); | 937 visitGenericType(type, argument); |
936 | 938 |
937 R visitDynamicType(DynamicType type, A argument) => | 939 R visitDynamicType(DynamicType type, A argument) => |
938 visitInterfaceType(type, argument); | 940 visitInterfaceType(type, argument); |
939 } | 941 } |
940 | 942 |
| 943 /** |
| 944 * Type visitor that determines the subtype relation two types. |
| 945 */ |
941 class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { | 946 class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
942 final Compiler compiler; | 947 final Compiler compiler; |
943 final DynamicType dynamicType; | 948 final DynamicType dynamicType; |
944 final VoidType voidType; | 949 final VoidType voidType; |
945 | 950 |
946 SubtypeVisitor(Compiler this.compiler, | 951 SubtypeVisitor(Compiler this.compiler, |
947 DynamicType this.dynamicType, | 952 DynamicType this.dynamicType, |
948 VoidType this.voidType); | 953 VoidType this.voidType); |
949 | 954 |
950 bool isSubtype(DartType t, DartType s) { | 955 bool isSubtype(DartType t, DartType s) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 return isSubtype(bound, s); | 1138 return isSubtype(bound, s); |
1134 } | 1139 } |
1135 } | 1140 } |
1136 | 1141 |
1137 class Types { | 1142 class Types { |
1138 final Compiler compiler; | 1143 final Compiler compiler; |
1139 // TODO(karlklose): should we have a class Void? | 1144 // TODO(karlklose): should we have a class Void? |
1140 final VoidType voidType; | 1145 final VoidType voidType; |
1141 final DynamicType dynamicType; | 1146 final DynamicType dynamicType; |
1142 final SubtypeVisitor subtypeVisitor; | 1147 final SubtypeVisitor subtypeVisitor; |
| 1148 final PotentialSubtypeVisitor potentialSubtypeVisitor; |
1143 | 1149 |
1144 factory Types(Compiler compiler, BaseClassElementX dynamicElement) { | 1150 factory Types(Compiler compiler, BaseClassElementX dynamicElement) { |
1145 LibraryElement library = new LibraryElementX(new Script(null, null)); | 1151 LibraryElement library = new LibraryElementX(new Script(null, null)); |
1146 VoidType voidType = new VoidType(new VoidElementX(library)); | 1152 VoidType voidType = new VoidType(new VoidElementX(library)); |
1147 DynamicType dynamicType = new DynamicType(dynamicElement); | 1153 DynamicType dynamicType = new DynamicType(dynamicElement); |
1148 dynamicElement.rawTypeCache = dynamicElement.thisType = dynamicType; | 1154 dynamicElement.rawTypeCache = dynamicElement.thisType = dynamicType; |
1149 SubtypeVisitor subtypeVisitor = | 1155 SubtypeVisitor subtypeVisitor = |
1150 new SubtypeVisitor(compiler, dynamicType, voidType); | 1156 new SubtypeVisitor(compiler, dynamicType, voidType); |
1151 return new Types.internal(compiler, voidType, dynamicType, subtypeVisitor); | 1157 PotentialSubtypeVisitor potentialSubtypeVisitor = |
| 1158 new PotentialSubtypeVisitor(compiler, dynamicType, voidType); |
| 1159 |
| 1160 return new Types.internal(compiler, voidType, dynamicType, |
| 1161 subtypeVisitor, potentialSubtypeVisitor); |
1152 } | 1162 } |
1153 | 1163 |
1154 Types.internal(this.compiler, this.voidType, this.dynamicType, | 1164 Types.internal(this.compiler, this.voidType, this.dynamicType, |
1155 this.subtypeVisitor); | 1165 this.subtypeVisitor, this.potentialSubtypeVisitor); |
1156 | 1166 |
1157 /** Returns true if t is a subtype of s */ | 1167 /** Returns true if t is a subtype of s */ |
1158 bool isSubtype(DartType t, DartType s) { | 1168 bool isSubtype(DartType t, DartType s) { |
1159 return subtypeVisitor.isSubtype(t, s); | 1169 return subtypeVisitor.isSubtype(t, s); |
1160 } | 1170 } |
1161 | 1171 |
1162 bool isAssignable(DartType r, DartType s) { | 1172 bool isAssignable(DartType r, DartType s) { |
1163 return subtypeVisitor.isAssignable(r, s); | 1173 return subtypeVisitor.isAssignable(r, s); |
1164 } | 1174 } |
1165 | 1175 |
| 1176 bool isPotentialSubtype(DartType t, DartType s) { |
| 1177 // TODO(johnniwinther): Return a set of variable points in the positive |
| 1178 // cases. |
| 1179 return potentialSubtypeVisitor.isSubtype(t, s); |
| 1180 } |
1166 | 1181 |
1167 /** | 1182 /** |
1168 * Helper method for performing substitution of a linked list of types. | 1183 * Helper method for performing substitution of a linked list of types. |
1169 * | 1184 * |
1170 * If no types are changed by the substitution, the [types] is returned | 1185 * If no types are changed by the substitution, the [types] is returned |
1171 * instead of a newly created linked list. | 1186 * instead of a newly created linked list. |
1172 */ | 1187 */ |
1173 static Link<DartType> substTypes(Link<DartType> types, | 1188 static Link<DartType> substTypes(Link<DartType> types, |
1174 Link<DartType> arguments, | 1189 Link<DartType> arguments, |
1175 Link<DartType> parameters) { | 1190 Link<DartType> parameters) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 /** | 1225 /** |
1211 * Returns the [ClassElement] which declares the type variables occurring in | 1226 * Returns the [ClassElement] which declares the type variables occurring in |
1212 * [type], or [:null:] if [type] does not contain type variables. | 1227 * [type], or [:null:] if [type] does not contain type variables. |
1213 */ | 1228 */ |
1214 static ClassElement getClassContext(DartType type) { | 1229 static ClassElement getClassContext(DartType type) { |
1215 TypeVariableType typeVariable = type.typeVariableOccurrence; | 1230 TypeVariableType typeVariable = type.typeVariableOccurrence; |
1216 if (typeVariable == null) return null; | 1231 if (typeVariable == null) return null; |
1217 return typeVariable.element.enclosingElement; | 1232 return typeVariable.element.enclosingElement; |
1218 } | 1233 } |
1219 } | 1234 } |
| 1235 |
| 1236 /** |
| 1237 * Type visitor that determines one type could a subtype of another given the |
| 1238 * right type variable substitution. The computation is approximate and returns |
| 1239 * [:false:] only if we are sure no such substitution exists. |
| 1240 */ |
| 1241 class PotentialSubtypeVisitor extends SubtypeVisitor { |
| 1242 PotentialSubtypeVisitor(Compiler compiler, |
| 1243 DynamicType dynamicType, |
| 1244 VoidType voidType) |
| 1245 : super(compiler, dynamicType, voidType); |
| 1246 |
| 1247 |
| 1248 bool isSubtype(DartType t, DartType s) { |
| 1249 if (t is TypeVariableType || s is TypeVariableType) { |
| 1250 return true; |
| 1251 } |
| 1252 return super.isSubtype(t, s); |
| 1253 } |
| 1254 } |
OLD | NEW |