| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 /// List of elements that the user has requested for reflection. | 334 /// List of elements that the user has requested for reflection. |
| 335 final Set<Element> targetsUsed = new Set<Element>(); | 335 final Set<Element> targetsUsed = new Set<Element>(); |
| 336 | 336 |
| 337 /// List of annotations provided by user that indicate that the annotated | 337 /// List of annotations provided by user that indicate that the annotated |
| 338 /// element must be retained. | 338 /// element must be retained. |
| 339 final Set<Element> metaTargetsUsed = new Set<Element>(); | 339 final Set<Element> metaTargetsUsed = new Set<Element>(); |
| 340 | 340 |
| 341 /// List of elements that the backend may use. | 341 /// List of elements that the backend may use. |
| 342 final Set<Element> helpersUsed = new Set<Element>(); | 342 final Set<Element> helpersUsed = new Set<Element>(); |
| 343 | 343 |
| 344 |
| 344 /// Set of typedefs that are used as type literals. | 345 /// Set of typedefs that are used as type literals. |
| 345 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); | 346 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); |
| 346 | 347 |
| 348 /// All the checked mode helpers. |
| 349 static const checkedModeHelpers = const [ |
| 350 const CheckedModeHelper(const SourceString('voidTypeCheck')), |
| 351 const CheckedModeHelper(const SourceString('stringTypeCast')), |
| 352 const CheckedModeHelper(const SourceString('stringTypeCheck')), |
| 353 const CheckedModeHelper(const SourceString('doubleTypeCast')), |
| 354 const CheckedModeHelper(const SourceString('doubleTypeCheck')), |
| 355 const CheckedModeHelper(const SourceString('numTypeCast')), |
| 356 const CheckedModeHelper(const SourceString('numTypeCheck')), |
| 357 const CheckedModeHelper(const SourceString('boolTypeCast')), |
| 358 const CheckedModeHelper(const SourceString('boolTypeCheck')), |
| 359 const CheckedModeHelper(const SourceString('intTypeCast')), |
| 360 const CheckedModeHelper(const SourceString('intTypeCheck')), |
| 361 const PropertyCheckedModeHelper( |
| 362 const SourceString('numberOrStringSuperNativeTypeCast')), |
| 363 const PropertyCheckedModeHelper( |
| 364 const SourceString('numberOrStringSuperNativeTypeCheck')), |
| 365 const PropertyCheckedModeHelper( |
| 366 const SourceString('numberOrStringSuperTypeCast')), |
| 367 const PropertyCheckedModeHelper( |
| 368 const SourceString('numberOrStringSuperTypeCheck')), |
| 369 const PropertyCheckedModeHelper( |
| 370 const SourceString('stringSuperNativeTypeCast')), |
| 371 const PropertyCheckedModeHelper( |
| 372 const SourceString('stringSuperNativeTypeCheck')), |
| 373 const PropertyCheckedModeHelper( |
| 374 const SourceString('stringSuperTypeCast')), |
| 375 const PropertyCheckedModeHelper( |
| 376 const SourceString('stringSuperTypeCheck')), |
| 377 const CheckedModeHelper(const SourceString('listTypeCast')), |
| 378 const CheckedModeHelper(const SourceString('listTypeCheck')), |
| 379 const PropertyCheckedModeHelper( |
| 380 const SourceString('listSuperNativeTypeCast')), |
| 381 const PropertyCheckedModeHelper( |
| 382 const SourceString('listSuperNativeTypeCheck')), |
| 383 const PropertyCheckedModeHelper( |
| 384 const SourceString('listSuperTypeCast')), |
| 385 const PropertyCheckedModeHelper( |
| 386 const SourceString('listSuperTypeCheck')), |
| 387 const PropertyCheckedModeHelper( |
| 388 const SourceString('interceptedTypeCast')), |
| 389 const PropertyCheckedModeHelper( |
| 390 const SourceString('interceptedTypeCheck')), |
| 391 const SubtypeCheckedModeHelper( |
| 392 const SourceString('subtypeCast')), |
| 393 const SubtypeCheckedModeHelper( |
| 394 const SourceString('assertSubtype')), |
| 395 const TypeVariableCheckedModeHelper( |
| 396 const SourceString('subtypeOfRuntimeTypeCast')), |
| 397 const TypeVariableCheckedModeHelper( |
| 398 const SourceString('assertSubtypeOfRuntimeType')), |
| 399 const FunctionTypeCheckedModeHelper( |
| 400 const SourceString('functionSubtypeCast')), |
| 401 const FunctionTypeCheckedModeHelper( |
| 402 const SourceString('assertFunctionSubtype')), |
| 403 const PropertyCheckedModeHelper( |
| 404 const SourceString('propertyTypeCast')), |
| 405 const PropertyCheckedModeHelper( |
| 406 const SourceString('propertyTypeCheck')) ]; |
| 407 |
| 408 // Checked mode helpers indexed by name. |
| 409 Map<String, CheckedModeHelper> checkedModeHelperByName = |
| 410 new Map<String, CheckedModeHelper>.fromIterable( |
| 411 checkedModeHelpers, |
| 412 key: (helper) => helper.name.slowToString()); |
| 413 |
| 347 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) | 414 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) |
| 348 : namer = determineNamer(compiler), | 415 : namer = determineNamer(compiler), |
| 349 oneShotInterceptors = new Map<String, Selector>(), | 416 oneShotInterceptors = new Map<String, Selector>(), |
| 350 interceptedElements = new Map<SourceString, Set<Element>>(), | 417 interceptedElements = new Map<SourceString, Set<Element>>(), |
| 351 rti = new RuntimeTypes(compiler), | 418 rti = new RuntimeTypes(compiler), |
| 352 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), | 419 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), |
| 353 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { | 420 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| 354 emitter = disableEval | 421 emitter = disableEval |
| 355 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) | 422 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) |
| 356 : new CodeEmitterTask(compiler, namer, generateSourceMap); | 423 : new CodeEmitterTask(compiler, namer, generateSourceMap); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 ClassElement cls, Enqueuer enqueuer) { | 669 ClassElement cls, Enqueuer enqueuer) { |
| 603 if (enqueuer.isResolutionQueue) { | 670 if (enqueuer.isResolutionQueue) { |
| 604 cls.ensureResolved(compiler); | 671 cls.ensureResolved(compiler); |
| 605 cls.forEachMember((ClassElement classElement, Element member) { | 672 cls.forEachMember((ClassElement classElement, Element member) { |
| 606 if (member.isSynthesized) return; | 673 if (member.isSynthesized) return; |
| 607 // All methods on [Object] are shadowed by [Interceptor]. | 674 // All methods on [Object] are shadowed by [Interceptor]. |
| 608 if (classElement == compiler.objectClass) return; | 675 if (classElement == compiler.objectClass) return; |
| 609 Set<Element> set = interceptedElements.putIfAbsent( | 676 Set<Element> set = interceptedElements.putIfAbsent( |
| 610 member.name, () => new Set<Element>()); | 677 member.name, () => new Set<Element>()); |
| 611 set.add(member); | 678 set.add(member); |
| 612 if (classElement == jsInterceptorClass) return; | 679 }, |
| 613 if (classElement.isMixinApplication) { | 680 includeSuperAndInjectedMembers: true); |
| 614 MixinApplicationElement mixinApplication = classElement; | 681 |
| 615 assert(member.getEnclosingClass() == mixinApplication.mixin); | 682 // Walk superclass chain to find mixins. |
| 683 for (; cls != null; cls = cls.superclass) { |
| 684 if (cls.isMixinApplication) { |
| 685 MixinApplicationElement mixinApplication = cls; |
| 616 classesMixedIntoNativeClasses.add(mixinApplication.mixin); | 686 classesMixedIntoNativeClasses.add(mixinApplication.mixin); |
| 617 } | 687 } |
| 618 }, | 688 } |
| 619 includeSuperAndInjectedMembers: true); | |
| 620 } | 689 } |
| 621 } | 690 } |
| 622 | 691 |
| 623 void addInterceptors(ClassElement cls, | 692 void addInterceptors(ClassElement cls, |
| 624 Enqueuer enqueuer, | 693 Enqueuer enqueuer, |
| 625 TreeElements elements) { | 694 TreeElements elements) { |
| 626 if (enqueuer.isResolutionQueue) { | 695 if (enqueuer.isResolutionQueue) { |
| 627 _interceptedClasses.add(jsInterceptorClass); | 696 _interceptedClasses.add(jsInterceptorClass); |
| 628 _interceptedClasses.add(cls); | 697 _interceptedClasses.add(cls); |
| 629 cls.ensureResolved(compiler); | 698 cls.ensureResolved(compiler); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 addInterceptors(jsBoolClass, world, elements); | 839 addInterceptors(jsBoolClass, world, elements); |
| 771 addInterceptors(jsNullClass, world, elements); | 840 addInterceptors(jsNullClass, world, elements); |
| 772 if (compiler.enableTypeAssertions) { | 841 if (compiler.enableTypeAssertions) { |
| 773 // Unconditionally register the helper that checks if the | 842 // Unconditionally register the helper that checks if the |
| 774 // expression in an if/while/for is a boolean. | 843 // expression in an if/while/for is a boolean. |
| 775 // TODO(ngeoffray): Should we have the resolver register those instead? | 844 // TODO(ngeoffray): Should we have the resolver register those instead? |
| 776 Element e = | 845 Element e = |
| 777 compiler.findHelper(const SourceString('boolConversionCheck')); | 846 compiler.findHelper(const SourceString('boolConversionCheck')); |
| 778 if (e != null) enqueue(world, e, elements); | 847 if (e != null) enqueue(world, e, elements); |
| 779 } | 848 } |
| 849 registerCheckedModeHelpers(elements); |
| 780 } | 850 } |
| 781 | 851 |
| 782 onResolutionComplete() => rti.computeClassesNeedingRti(); | 852 onResolutionComplete() => rti.computeClassesNeedingRti(); |
| 783 | 853 |
| 784 void registerStringInterpolation(TreeElements elements) { | 854 void registerStringInterpolation(TreeElements elements) { |
| 785 enqueueInResolution(getStringInterpolationHelper(), elements); | 855 enqueueInResolution(getStringInterpolationHelper(), elements); |
| 786 } | 856 } |
| 787 | 857 |
| 788 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { | 858 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { |
| 789 void ensure(ClassElement classElement) { | 859 void ensure(ClassElement classElement) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 enqueueInResolution(getCreateRuntimeType(), elements); | 942 enqueueInResolution(getCreateRuntimeType(), elements); |
| 873 } | 943 } |
| 874 | 944 |
| 875 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { | 945 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| 876 type = type.unalias(compiler); | 946 type = type.unalias(compiler); |
| 877 enqueueClass(world, compiler.boolClass, elements); | 947 enqueueClass(world, compiler.boolClass, elements); |
| 878 bool inCheckedMode = compiler.enableTypeAssertions; | 948 bool inCheckedMode = compiler.enableTypeAssertions; |
| 879 // [registerIsCheck] is also called for checked mode checks, so we | 949 // [registerIsCheck] is also called for checked mode checks, so we |
| 880 // need to register checked mode helpers. | 950 // need to register checked mode helpers. |
| 881 if (inCheckedMode) { | 951 if (inCheckedMode) { |
| 882 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); | 952 if (!world.isResolutionQueue) { |
| 883 if (helper != null) enqueue(world, helper.getElement(compiler), elements); | 953 // All helpers are added to resolution queue in enqueueHelpers. These |
| 884 // We also need the native variant of the check (for DOM types). | 954 // calls to enqueueInResolution serve as assertions that the helper was |
| 885 helper = getNativeCheckedModeHelper(type, typeCast: false); | 955 // in fact added. |
| 886 if (helper != null) enqueue(world, helper.getElement(compiler), elements); | 956 // TODO(13155): Find a way to enqueue helpers lazily. |
| 957 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); |
| 958 if (helper != null) { |
| 959 enqueue(world, helper.getElement(compiler), elements); |
| 960 } |
| 961 // We also need the native variant of the check (for DOM types). |
| 962 helper = getNativeCheckedModeHelper(type, typeCast: false); |
| 963 if (helper != null) { |
| 964 enqueue(world, helper.getElement(compiler), elements); |
| 965 } |
| 966 } |
| 887 } | 967 } |
| 888 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; | 968 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
| 889 if (!type.isRaw || type.containsTypeVariables) { | 969 if (!type.isRaw || type.containsTypeVariables) { |
| 890 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 970 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
| 891 enqueueInResolution(getGetRuntimeTypeInfo(), elements); | 971 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
| 892 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 972 enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
| 893 if (inCheckedMode) { | 973 if (inCheckedMode) { |
| 894 enqueueInResolution(getAssertSubtype(), elements); | 974 enqueueInResolution(getAssertSubtype(), elements); |
| 895 } | 975 } |
| 896 enqueueInResolution(getCheckSubtype(), elements); | 976 enqueueInResolution(getCheckSubtype(), elements); |
| 897 if (isTypeVariable) { | 977 if (isTypeVariable) { |
| 898 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); | 978 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); |
| 899 if (inCheckedMode) { | 979 if (inCheckedMode) { |
| 900 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 980 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
| 901 } | 981 } |
| 902 } | 982 } |
| 903 enqueueClass(world, compiler.listClass, elements); | 983 enqueueClass(world, compiler.listClass, elements); |
| 904 } | 984 } |
| 905 if (type is FunctionType) { | 985 if (type is FunctionType) { |
| 906 enqueueInResolution(getCheckFunctionSubtype(), elements); | 986 enqueueInResolution(getCheckFunctionSubtype(), elements); |
| 907 } | 987 } |
| 908 if (type.element.isNative()) { | 988 if (type.element.isNative()) { |
| 909 // We will neeed to add the "$is" and "$as" properties on the | 989 // We will neeed to add the "$is" and "$as" properties on the |
| 910 // JavaScript object prototype, so we make sure | 990 // JavaScript object prototype, so we make sure |
| 911 // [:defineProperty:] is compiled. | 991 // [:defineProperty:] is compiled. |
| 912 enqueue(world, | 992 enqueue(world, |
| 913 compiler.findHelper(const SourceString('defineProperty')), | 993 compiler.findHelper(const SourceString('defineProperty')), |
| 914 elements); | 994 elements); |
| 915 } | 995 } |
| 916 } | 996 } |
| 917 | 997 |
| 918 void registerAsCheck(DartType type, TreeElements elements) { | 998 void registerAsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| 919 type = type.unalias(compiler); | 999 type = type.unalias(compiler); |
| 920 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); | 1000 if (!world.isResolutionQueue) { |
| 921 enqueueInResolution(helper.getElement(compiler), elements); | 1001 // All helpers are added to resolution queue in enqueueHelpers. These |
| 922 // We also need the native variant of the check (for DOM types). | 1002 // calls to enqueueInResolution serve as assertions that the helper was in |
| 923 helper = getNativeCheckedModeHelper(type, typeCast: true); | 1003 // fact added. |
| 924 if (helper != null) { | 1004 // TODO(13155): Find a way to enqueue helpers lazily. |
| 1005 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); |
| 925 enqueueInResolution(helper.getElement(compiler), elements); | 1006 enqueueInResolution(helper.getElement(compiler), elements); |
| 1007 // We also need the native variant of the check (for DOM types). |
| 1008 helper = getNativeCheckedModeHelper(type, typeCast: true); |
| 1009 if (helper != null) { |
| 1010 enqueueInResolution(helper.getElement(compiler), elements); |
| 1011 } |
| 926 } | 1012 } |
| 927 } | 1013 } |
| 928 | 1014 |
| 929 void registerThrowNoSuchMethod(TreeElements elements) { | 1015 void registerThrowNoSuchMethod(TreeElements elements) { |
| 930 enqueueInResolution(getThrowNoSuchMethod(), elements); | 1016 enqueueInResolution(getThrowNoSuchMethod(), elements); |
| 931 // Also register the types of the arguments passed to this method. | 1017 // Also register the types of the arguments passed to this method. |
| 932 enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements); | 1018 enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements); |
| 933 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements); | 1019 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements); |
| 934 } | 1020 } |
| 935 | 1021 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 type, typeCast: typeCast, nativeCheckOnly: true); | 1251 type, typeCast: typeCast, nativeCheckOnly: true); |
| 1166 } | 1252 } |
| 1167 | 1253 |
| 1168 /** | 1254 /** |
| 1169 * Returns the checked mode helper for the type check/type cast for [type]. If | 1255 * Returns the checked mode helper for the type check/type cast for [type]. If |
| 1170 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. | 1256 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. |
| 1171 */ | 1257 */ |
| 1172 CheckedModeHelper getCheckedModeHelperInternal(DartType type, | 1258 CheckedModeHelper getCheckedModeHelperInternal(DartType type, |
| 1173 {bool typeCast, | 1259 {bool typeCast, |
| 1174 bool nativeCheckOnly}) { | 1260 bool nativeCheckOnly}) { |
| 1261 String name = getCheckedModeHelperNameInternal(type, |
| 1262 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); |
| 1263 if (name == null) return null; |
| 1264 CheckedModeHelper helper = checkedModeHelperByName[name]; |
| 1265 assert(helper != null); |
| 1266 return helper; |
| 1267 } |
| 1268 |
| 1269 String getCheckedModeHelperNameInternal(DartType type, |
| 1270 {bool typeCast, |
| 1271 bool nativeCheckOnly}) { |
| 1175 assert(type.kind != TypeKind.TYPEDEF); | 1272 assert(type.kind != TypeKind.TYPEDEF); |
| 1176 Element element = type.element; | 1273 Element element = type.element; |
| 1177 bool nativeCheck = nativeCheckOnly || | 1274 bool nativeCheck = nativeCheckOnly || |
| 1178 emitter.nativeEmitter.requiresNativeIsCheck(element); | 1275 emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 1179 if (type == compiler.types.voidType) { | 1276 if (type == compiler.types.voidType) { |
| 1180 assert(!typeCast); // Cannot cast to void. | 1277 assert(!typeCast); // Cannot cast to void. |
| 1181 if (nativeCheckOnly) return null; | 1278 if (nativeCheckOnly) return null; |
| 1182 return const CheckedModeHelper(const SourceString('voidTypeCheck')); | 1279 return 'voidTypeCheck'; |
| 1183 } else if (element == jsStringClass || element == compiler.stringClass) { | 1280 } else if (element == jsStringClass || element == compiler.stringClass) { |
| 1184 if (nativeCheckOnly) return null; | 1281 if (nativeCheckOnly) return null; |
| 1185 return typeCast | 1282 return typeCast |
| 1186 ? const CheckedModeHelper(const SourceString("stringTypeCast")) | 1283 ? 'stringTypeCast' |
| 1187 : const CheckedModeHelper(const SourceString('stringTypeCheck')); | 1284 : 'stringTypeCheck'; |
| 1188 } else if (element == jsDoubleClass || element == compiler.doubleClass) { | 1285 } else if (element == jsDoubleClass || element == compiler.doubleClass) { |
| 1189 if (nativeCheckOnly) return null; | 1286 if (nativeCheckOnly) return null; |
| 1190 return typeCast | 1287 return typeCast |
| 1191 ? const CheckedModeHelper(const SourceString("doubleTypeCast")) | 1288 ? 'doubleTypeCast' |
| 1192 : const CheckedModeHelper(const SourceString('doubleTypeCheck')); | 1289 : 'doubleTypeCheck'; |
| 1193 } else if (element == jsNumberClass || element == compiler.numClass) { | 1290 } else if (element == jsNumberClass || element == compiler.numClass) { |
| 1194 if (nativeCheckOnly) return null; | 1291 if (nativeCheckOnly) return null; |
| 1195 return typeCast | 1292 return typeCast |
| 1196 ? const CheckedModeHelper(const SourceString("numTypeCast")) | 1293 ? 'numTypeCast' |
| 1197 : const CheckedModeHelper(const SourceString('numTypeCheck')); | 1294 : 'numTypeCheck'; |
| 1198 } else if (element == jsBoolClass || element == compiler.boolClass) { | 1295 } else if (element == jsBoolClass || element == compiler.boolClass) { |
| 1199 if (nativeCheckOnly) return null; | 1296 if (nativeCheckOnly) return null; |
| 1200 return typeCast | 1297 return typeCast |
| 1201 ? const CheckedModeHelper(const SourceString("boolTypeCast")) | 1298 ? 'boolTypeCast' |
| 1202 : const CheckedModeHelper(const SourceString('boolTypeCheck')); | 1299 : 'boolTypeCheck'; |
| 1203 } else if (element == jsIntClass || element == compiler.intClass) { | 1300 } else if (element == jsIntClass || element == compiler.intClass) { |
| 1204 if (nativeCheckOnly) return null; | 1301 if (nativeCheckOnly) return null; |
| 1205 return typeCast | 1302 return typeCast |
| 1206 ? const CheckedModeHelper(const SourceString("intTypeCast")) | 1303 ? 'intTypeCast' |
| 1207 : const CheckedModeHelper(const SourceString('intTypeCheck')); | 1304 : 'intTypeCheck'; |
| 1208 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { | 1305 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { |
| 1209 if (nativeCheck) { | 1306 if (nativeCheck) { |
| 1210 return typeCast | 1307 return typeCast |
| 1211 ? const PropertyCheckedModeHelper( | 1308 ? 'numberOrStringSuperNativeTypeCast' |
| 1212 const SourceString("numberOrStringSuperNativeTypeCast")) | 1309 : 'numberOrStringSuperNativeTypeCheck'; |
| 1213 : const PropertyCheckedModeHelper( | |
| 1214 const SourceString('numberOrStringSuperNativeTypeCheck')); | |
| 1215 } else { | 1310 } else { |
| 1216 return typeCast | 1311 return typeCast |
| 1217 ? const PropertyCheckedModeHelper( | 1312 ? 'numberOrStringSuperTypeCast' |
| 1218 const SourceString("numberOrStringSuperTypeCast")) | 1313 : 'numberOrStringSuperTypeCheck'; |
| 1219 : const PropertyCheckedModeHelper( | |
| 1220 const SourceString('numberOrStringSuperTypeCheck')); | |
| 1221 } | 1314 } |
| 1222 } else if (Elements.isStringOnlySupertype(element, compiler)) { | 1315 } else if (Elements.isStringOnlySupertype(element, compiler)) { |
| 1223 if (nativeCheck) { | 1316 if (nativeCheck) { |
| 1224 return typeCast | 1317 return typeCast |
| 1225 ? const PropertyCheckedModeHelper( | 1318 ? 'stringSuperNativeTypeCast' |
| 1226 const SourceString("stringSuperNativeTypeCast")) | 1319 : 'stringSuperNativeTypeCheck'; |
| 1227 : const PropertyCheckedModeHelper( | |
| 1228 const SourceString('stringSuperNativeTypeCheck')); | |
| 1229 } else { | 1320 } else { |
| 1230 return typeCast | 1321 return typeCast |
| 1231 ? const PropertyCheckedModeHelper( | 1322 ? 'stringSuperTypeCast' |
| 1232 const SourceString("stringSuperTypeCast")) | 1323 : 'stringSuperTypeCheck'; |
| 1233 : const PropertyCheckedModeHelper( | |
| 1234 const SourceString('stringSuperTypeCheck')); | |
| 1235 } | 1324 } |
| 1236 } else if ((element == compiler.listClass || element == jsArrayClass) && | 1325 } else if ((element == compiler.listClass || element == jsArrayClass) && |
| 1237 type.isRaw) { | 1326 type.isRaw) { |
| 1238 if (nativeCheckOnly) return null; | 1327 if (nativeCheckOnly) return null; |
| 1239 return typeCast | 1328 return typeCast |
| 1240 ? const CheckedModeHelper(const SourceString("listTypeCast")) | 1329 ? 'listTypeCast' |
| 1241 : const CheckedModeHelper(const SourceString('listTypeCheck')); | 1330 : 'listTypeCheck'; |
| 1242 } else { | 1331 } else { |
| 1243 if (Elements.isListSupertype(element, compiler)) { | 1332 if (Elements.isListSupertype(element, compiler)) { |
| 1244 if (nativeCheck) { | 1333 if (nativeCheck) { |
| 1245 return typeCast | 1334 return typeCast |
| 1246 ? const PropertyCheckedModeHelper( | 1335 ? 'listSuperNativeTypeCast' |
| 1247 const SourceString("listSuperNativeTypeCast")) | 1336 : 'listSuperNativeTypeCheck'; |
| 1248 : const PropertyCheckedModeHelper( | |
| 1249 const SourceString('listSuperNativeTypeCheck')); | |
| 1250 } else { | 1337 } else { |
| 1251 return typeCast | 1338 return typeCast |
| 1252 ? const PropertyCheckedModeHelper( | 1339 ? 'listSuperTypeCast' |
| 1253 const SourceString("listSuperTypeCast")) | 1340 : 'listSuperTypeCheck'; |
| 1254 : const PropertyCheckedModeHelper( | |
| 1255 const SourceString('listSuperTypeCheck')); | |
| 1256 } | 1341 } |
| 1257 } else { | 1342 } else { |
| 1258 if (nativeCheck) { | 1343 if (nativeCheck) { |
| 1259 // TODO(karlklose): can we get rid of this branch when we use | 1344 // TODO(karlklose): can we get rid of this branch when we use |
| 1260 // interceptors? | 1345 // interceptors? |
| 1261 return typeCast | 1346 return typeCast |
| 1262 ? const PropertyCheckedModeHelper( | 1347 ? 'interceptedTypeCast' |
| 1263 const SourceString("interceptedTypeCast")) | 1348 : 'interceptedTypeCheck'; |
| 1264 : const PropertyCheckedModeHelper( | |
| 1265 const SourceString('interceptedTypeCheck')); | |
| 1266 } else { | 1349 } else { |
| 1267 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { | 1350 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { |
| 1268 return typeCast | 1351 return typeCast |
| 1269 ? const SubtypeCheckedModeHelper( | 1352 ? 'subtypeCast' |
| 1270 const SourceString('subtypeCast')) | 1353 : 'assertSubtype'; |
| 1271 : const SubtypeCheckedModeHelper( | |
| 1272 const SourceString('assertSubtype')); | |
| 1273 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1354 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 1274 return typeCast | 1355 return typeCast |
| 1275 ? const TypeVariableCheckedModeHelper( | 1356 ? 'subtypeOfRuntimeTypeCast' |
| 1276 const SourceString('subtypeOfRuntimeTypeCast')) | 1357 : 'assertSubtypeOfRuntimeType'; |
| 1277 : const TypeVariableCheckedModeHelper( | |
| 1278 const SourceString('assertSubtypeOfRuntimeType')); | |
| 1279 } else if (type.kind == TypeKind.FUNCTION) { | 1358 } else if (type.kind == TypeKind.FUNCTION) { |
| 1280 return typeCast | 1359 return typeCast |
| 1281 ? const FunctionTypeCheckedModeHelper( | 1360 ? 'functionSubtypeCast' |
| 1282 const SourceString('functionSubtypeCast')) | 1361 : 'assertFunctionSubtype'; |
| 1283 : const FunctionTypeCheckedModeHelper( | |
| 1284 const SourceString('assertFunctionSubtype')); | |
| 1285 } else { | 1362 } else { |
| 1286 return typeCast | 1363 return typeCast |
| 1287 ? const PropertyCheckedModeHelper( | 1364 ? 'propertyTypeCast' |
| 1288 const SourceString('propertyTypeCast')) | 1365 : 'propertyTypeCheck'; |
| 1289 : const PropertyCheckedModeHelper( | |
| 1290 const SourceString('propertyTypeCheck')); | |
| 1291 } | 1366 } |
| 1292 } | 1367 } |
| 1293 } | 1368 } |
| 1294 } | 1369 } |
| 1295 } | 1370 } |
| 1296 | 1371 |
| 1372 void registerCheckedModeHelpers(TreeElements elements) { |
| 1373 // We register all the helpers in the resolution queue. |
| 1374 // TODO(13155): Find a way to register fewer helpers. |
| 1375 for (CheckedModeHelper helper in checkedModeHelpers) { |
| 1376 enqueueInResolution(helper.getElement(compiler), elements); |
| 1377 } |
| 1378 } |
| 1379 |
| 1297 /** | 1380 /** |
| 1298 * Returns [:true:] if the checking of [type] is performed directly on the | 1381 * Returns [:true:] if the checking of [type] is performed directly on the |
| 1299 * object and not on an interceptor. | 1382 * object and not on an interceptor. |
| 1300 */ | 1383 */ |
| 1301 bool hasDirectCheckFor(DartType type) { | 1384 bool hasDirectCheckFor(DartType type) { |
| 1302 Element element = type.element; | 1385 Element element = type.element; |
| 1303 return element == compiler.stringClass || | 1386 return element == compiler.stringClass || |
| 1304 element == compiler.boolClass || | 1387 element == compiler.boolClass || |
| 1305 element == compiler.numClass || | 1388 element == compiler.numClass || |
| 1306 element == compiler.intClass || | 1389 element == compiler.intClass || |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 copy(constant.values); | 1779 copy(constant.values); |
| 1697 copy(constant.protoValue); | 1780 copy(constant.protoValue); |
| 1698 copy(constant); | 1781 copy(constant); |
| 1699 } | 1782 } |
| 1700 | 1783 |
| 1701 void visitConstructed(ConstructedConstant constant) { | 1784 void visitConstructed(ConstructedConstant constant) { |
| 1702 copy(constant.fields); | 1785 copy(constant.fields); |
| 1703 copy(constant); | 1786 copy(constant); |
| 1704 } | 1787 } |
| 1705 } | 1788 } |
| OLD | NEW |