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 js_backend.backend; | 5 library js_backend.backend; |
6 | 6 |
7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
8 | 8 |
9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
10 | 10 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 TypeMask get numType => compiler.commonMasks.numType; | 338 TypeMask get numType => compiler.commonMasks.numType; |
339 TypeMask get boolType => compiler.commonMasks.boolType; | 339 TypeMask get boolType => compiler.commonMasks.boolType; |
340 TypeMask get dynamicType => compiler.commonMasks.dynamicType; | 340 TypeMask get dynamicType => compiler.commonMasks.dynamicType; |
341 TypeMask get nullType => compiler.commonMasks.nullType; | 341 TypeMask get nullType => compiler.commonMasks.nullType; |
342 TypeMask get emptyType => const TypeMask.nonNullEmpty(); | 342 TypeMask get emptyType => const TypeMask.nonNullEmpty(); |
343 TypeMask get nonNullType => compiler.commonMasks.nonNullType; | 343 TypeMask get nonNullType => compiler.commonMasks.nonNullType; |
344 | 344 |
345 TypeMask _indexablePrimitiveTypeCache; | 345 TypeMask _indexablePrimitiveTypeCache; |
346 TypeMask get indexablePrimitiveType { | 346 TypeMask get indexablePrimitiveType { |
347 if (_indexablePrimitiveTypeCache == null) { | 347 if (_indexablePrimitiveTypeCache == null) { |
348 _indexablePrimitiveTypeCache = | 348 _indexablePrimitiveTypeCache = new TypeMask.nonNullSubtype( |
349 new TypeMask.nonNullSubtype(helpers.jsIndexableClass, compiler.world); | 349 helpers.jsIndexableClass, compiler.closedWorld); |
350 } | 350 } |
351 return _indexablePrimitiveTypeCache; | 351 return _indexablePrimitiveTypeCache; |
352 } | 352 } |
353 | 353 |
354 TypeMask _readableArrayTypeCache; | 354 TypeMask _readableArrayTypeCache; |
355 TypeMask get readableArrayType { | 355 TypeMask get readableArrayType { |
356 if (_readableArrayTypeCache == null) { | 356 if (_readableArrayTypeCache == null) { |
357 _readableArrayTypeCache = | 357 _readableArrayTypeCache = new TypeMask.nonNullSubclass( |
358 new TypeMask.nonNullSubclass(helpers.jsArrayClass, compiler.world); | 358 helpers.jsArrayClass, compiler.closedWorld); |
359 } | 359 } |
360 return _readableArrayTypeCache; | 360 return _readableArrayTypeCache; |
361 } | 361 } |
362 | 362 |
363 TypeMask _mutableArrayTypeCache; | 363 TypeMask _mutableArrayTypeCache; |
364 TypeMask get mutableArrayType { | 364 TypeMask get mutableArrayType { |
365 if (_mutableArrayTypeCache == null) { | 365 if (_mutableArrayTypeCache == null) { |
366 _mutableArrayTypeCache = new TypeMask.nonNullSubclass( | 366 _mutableArrayTypeCache = new TypeMask.nonNullSubclass( |
367 helpers.jsMutableArrayClass, compiler.world); | 367 helpers.jsMutableArrayClass, compiler.closedWorld); |
368 } | 368 } |
369 return _mutableArrayTypeCache; | 369 return _mutableArrayTypeCache; |
370 } | 370 } |
371 | 371 |
372 TypeMask _fixedArrayTypeCache; | 372 TypeMask _fixedArrayTypeCache; |
373 TypeMask get fixedArrayType { | 373 TypeMask get fixedArrayType { |
374 if (_fixedArrayTypeCache == null) { | 374 if (_fixedArrayTypeCache == null) { |
375 _fixedArrayTypeCache = | 375 _fixedArrayTypeCache = new TypeMask.nonNullExact( |
376 new TypeMask.nonNullExact(helpers.jsFixedArrayClass, compiler.world); | 376 helpers.jsFixedArrayClass, compiler.closedWorld); |
377 } | 377 } |
378 return _fixedArrayTypeCache; | 378 return _fixedArrayTypeCache; |
379 } | 379 } |
380 | 380 |
381 TypeMask _extendableArrayTypeCache; | 381 TypeMask _extendableArrayTypeCache; |
382 TypeMask get extendableArrayType { | 382 TypeMask get extendableArrayType { |
383 if (_extendableArrayTypeCache == null) { | 383 if (_extendableArrayTypeCache == null) { |
384 _extendableArrayTypeCache = new TypeMask.nonNullExact( | 384 _extendableArrayTypeCache = new TypeMask.nonNullExact( |
385 helpers.jsExtendableArrayClass, compiler.world); | 385 helpers.jsExtendableArrayClass, compiler.closedWorld); |
386 } | 386 } |
387 return _extendableArrayTypeCache; | 387 return _extendableArrayTypeCache; |
388 } | 388 } |
389 | 389 |
390 TypeMask _unmodifiableArrayTypeCache; | 390 TypeMask _unmodifiableArrayTypeCache; |
391 TypeMask get unmodifiableArrayType { | 391 TypeMask get unmodifiableArrayType { |
392 if (_unmodifiableArrayTypeCache == null) { | 392 if (_unmodifiableArrayTypeCache == null) { |
393 _unmodifiableArrayTypeCache = new TypeMask.nonNullExact( | 393 _unmodifiableArrayTypeCache = new TypeMask.nonNullExact( |
394 helpers.jsUnmodifiableArrayClass, compiler.world); | 394 helpers.jsUnmodifiableArrayClass, compiler.closedWorld); |
395 } | 395 } |
396 return _fixedArrayTypeCache; | 396 return _fixedArrayTypeCache; |
397 } | 397 } |
398 | 398 |
399 /// Maps special classes to their implementation (JSXxx) class. | 399 /// Maps special classes to their implementation (JSXxx) class. |
400 Map<ClassElement, ClassElement> implementationClasses; | 400 Map<ClassElement, ClassElement> implementationClasses; |
401 | 401 |
402 bool needToInitializeIsolateAffinityTag = false; | 402 bool needToInitializeIsolateAffinityTag = false; |
403 bool needToInitializeDispatchProperty = false; | 403 bool needToInitializeDispatchProperty = false; |
404 | 404 |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 if (elements == null) return null; | 901 if (elements == null) return null; |
902 return elements | 902 return elements |
903 .where((element) => classesMixedIntoInterceptedClasses | 903 .where((element) => classesMixedIntoInterceptedClasses |
904 .contains(element.enclosingClass)) | 904 .contains(element.enclosingClass)) |
905 .toSet(); | 905 .toSet(); |
906 }); | 906 }); |
907 | 907 |
908 if (elements == null) return false; | 908 if (elements == null) return false; |
909 if (elements.isEmpty) return false; | 909 if (elements.isEmpty) return false; |
910 return elements.any((element) { | 910 return elements.any((element) { |
911 return selector.applies(element, compiler.world) && | 911 return selector.applies(element, compiler.closedWorld) && |
912 (mask == null || mask.canHit(element, selector, compiler.world)); | 912 (mask == null || |
| 913 mask.canHit(element, selector, compiler.closedWorld)); |
913 }); | 914 }); |
914 } | 915 } |
915 | 916 |
916 /// True if the given class is an internal class used for type inference | 917 /// True if the given class is an internal class used for type inference |
917 /// and never exists at runtime. | 918 /// and never exists at runtime. |
918 bool isCompileTimeOnlyClass(ClassElement class_) { | 919 bool isCompileTimeOnlyClass(ClassElement class_) { |
919 return class_ == helpers.jsPositiveIntClass || | 920 return class_ == helpers.jsPositiveIntClass || |
920 class_ == helpers.jsUInt32Class || | 921 class_ == helpers.jsUInt32Class || |
921 class_ == helpers.jsUInt31Class || | 922 class_ == helpers.jsUInt31Class || |
922 class_ == helpers.jsFixedArrayClass || | 923 class_ == helpers.jsFixedArrayClass || |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 Set<ClassElement> nativeSubclasses = | 959 Set<ClassElement> nativeSubclasses = |
959 nativeSubclassesOfMixin(classElement); | 960 nativeSubclassesOfMixin(classElement); |
960 if (nativeSubclasses != null) result.addAll(nativeSubclasses); | 961 if (nativeSubclasses != null) result.addAll(nativeSubclasses); |
961 } | 962 } |
962 } | 963 } |
963 return result; | 964 return result; |
964 }); | 965 }); |
965 } | 966 } |
966 | 967 |
967 Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) { | 968 Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) { |
968 ClassWorld classWorld = compiler.world; | 969 ClassWorld classWorld = compiler.closedWorld; |
969 Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin); | 970 Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin); |
970 Set<ClassElement> result = null; | 971 Set<ClassElement> result = null; |
971 for (MixinApplicationElement use in uses) { | 972 for (MixinApplicationElement use in uses) { |
972 classWorld.forEachStrictSubclassOf(use, (ClassElement subclass) { | 973 classWorld.forEachStrictSubclassOf(use, (ClassElement subclass) { |
973 if (isNativeOrExtendsNative(subclass)) { | 974 if (isNativeOrExtendsNative(subclass)) { |
974 if (result == null) result = new Set<ClassElement>(); | 975 if (result == null) result = new Set<ClassElement>(); |
975 result.add(subclass); | 976 result.add(subclass); |
976 } | 977 } |
977 }); | 978 }); |
978 } | 979 } |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 element == helpers.jsUnmodifiableArrayClass; | 1862 element == helpers.jsUnmodifiableArrayClass; |
1862 } | 1863 } |
1863 | 1864 |
1864 bool mayGenerateInstanceofCheck(DartType type) { | 1865 bool mayGenerateInstanceofCheck(DartType type) { |
1865 // We can use an instanceof check for raw types that have no subclass that | 1866 // We can use an instanceof check for raw types that have no subclass that |
1866 // is mixed-in or in an implements clause. | 1867 // is mixed-in or in an implements clause. |
1867 | 1868 |
1868 if (!type.isRaw) return false; | 1869 if (!type.isRaw) return false; |
1869 ClassElement classElement = type.element; | 1870 ClassElement classElement = type.element; |
1870 if (isInterceptorClass(classElement)) return false; | 1871 if (isInterceptorClass(classElement)) return false; |
1871 return compiler.world.hasOnlySubclasses(classElement); | 1872 return compiler.closedWorld.hasOnlySubclasses(classElement); |
1872 } | 1873 } |
1873 | 1874 |
1874 bool isNullImplementation(ClassElement cls) { | 1875 bool isNullImplementation(ClassElement cls) { |
1875 return cls == helpers.jsNullClass; | 1876 return cls == helpers.jsNullClass; |
1876 } | 1877 } |
1877 | 1878 |
1878 ClassElement get intImplementation => helpers.jsIntClass; | 1879 ClassElement get intImplementation => helpers.jsIntClass; |
1879 ClassElement get uint32Implementation => helpers.jsUInt32Class; | 1880 ClassElement get uint32Implementation => helpers.jsUInt32Class; |
1880 ClassElement get uint31Implementation => helpers.jsUInt31Class; | 1881 ClassElement get uint31Implementation => helpers.jsUInt31Class; |
1881 ClassElement get positiveIntImplementation => helpers.jsPositiveIntClass; | 1882 ClassElement get positiveIntImplementation => helpers.jsPositiveIntClass; |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2154 } | 2155 } |
2155 }); | 2156 }); |
2156 // 3) all members, including fields via getter/setters (if resolved) | 2157 // 3) all members, including fields via getter/setters (if resolved) |
2157 cls.forEachClassMember((Member member) { | 2158 cls.forEachClassMember((Member member) { |
2158 if (resolution.hasBeenProcessed(member.element)) { | 2159 if (resolution.hasBeenProcessed(member.element)) { |
2159 memberNames.add(member.name); | 2160 memberNames.add(member.name); |
2160 reflectableMembers.add(member.element); | 2161 reflectableMembers.add(member.element); |
2161 } | 2162 } |
2162 }); | 2163 }); |
2163 // 4) all overriding members of subclasses/subtypes (should be resolved) | 2164 // 4) all overriding members of subclasses/subtypes (should be resolved) |
2164 if (compiler.world.hasAnyStrictSubtype(cls)) { | 2165 if (compiler.closedWorld.hasAnyStrictSubtype(cls)) { |
2165 compiler.world.forEachStrictSubtypeOf(cls, (ClassElement subcls) { | 2166 compiler.closedWorld.forEachStrictSubtypeOf(cls, |
| 2167 (ClassElement subcls) { |
2166 subcls.forEachClassMember((Member member) { | 2168 subcls.forEachClassMember((Member member) { |
2167 if (memberNames.contains(member.name)) { | 2169 if (memberNames.contains(member.name)) { |
2168 // TODO(20993): find out why this assertion fails. | 2170 // TODO(20993): find out why this assertion fails. |
2169 // assert(invariant(member.element, | 2171 // assert(invariant(member.element, |
2170 // resolution.hasBeenProcessed(member.element))); | 2172 // resolution.hasBeenProcessed(member.element))); |
2171 if (resolution.hasBeenProcessed(member.element)) { | 2173 if (resolution.hasBeenProcessed(member.element)) { |
2172 reflectableMembers.add(member.element); | 2174 reflectableMembers.add(member.element); |
2173 } | 2175 } |
2174 } | 2176 } |
2175 }); | 2177 }); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2234 // As we do not think about closures as classes, yet, we have to make sure | 2236 // As we do not think about closures as classes, yet, we have to make sure |
2235 // their superclasses are available for reflection manually. | 2237 // their superclasses are available for reflection manually. |
2236 if (foundClosure) { | 2238 if (foundClosure) { |
2237 reflectableMembers.add(helpers.closureClass); | 2239 reflectableMembers.add(helpers.closureClass); |
2238 } | 2240 } |
2239 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; | 2241 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; |
2240 if (closurizedMembers.any(reflectableMembers.contains)) { | 2242 if (closurizedMembers.any(reflectableMembers.contains)) { |
2241 reflectableMembers.add(helpers.boundClosureClass); | 2243 reflectableMembers.add(helpers.boundClosureClass); |
2242 } | 2244 } |
2243 // Add typedefs. | 2245 // Add typedefs. |
2244 reflectableMembers | 2246 reflectableMembers.addAll( |
2245 .addAll(compiler.world.allTypedefs.where(referencedFromMirrorSystem)); | 2247 compiler.closedWorld.allTypedefs.where(referencedFromMirrorSystem)); |
2246 // Register all symbols of reflectable elements | 2248 // Register all symbols of reflectable elements |
2247 for (Element element in reflectableMembers) { | 2249 for (Element element in reflectableMembers) { |
2248 symbolsUsed.add(element.name); | 2250 symbolsUsed.add(element.name); |
2249 } | 2251 } |
2250 _membersNeededForReflection = reflectableMembers; | 2252 _membersNeededForReflection = reflectableMembers; |
2251 } | 2253 } |
2252 | 2254 |
2253 // TODO(20791): compute closure classes after resolution and move this code to | 2255 // TODO(20791): compute closure classes after resolution and move this code to |
2254 // [computeMembersNeededForReflection]. | 2256 // [computeMembersNeededForReflection]. |
2255 void maybeMarkClosureAsNeededForReflection( | 2257 void maybeMarkClosureAsNeededForReflection( |
(...skipping 22 matching lines...) Expand all Loading... |
2278 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); | 2280 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); |
2279 return new jsAst.Call(helperExpression, arguments); | 2281 return new jsAst.Call(helperExpression, arguments); |
2280 } | 2282 } |
2281 | 2283 |
2282 bool isTypedArray(TypeMask mask) { | 2284 bool isTypedArray(TypeMask mask) { |
2283 // Just checking for [:TypedData:] is not sufficient, as it is an | 2285 // Just checking for [:TypedData:] is not sufficient, as it is an |
2284 // abstract class any user-defined class can implement. So we also | 2286 // abstract class any user-defined class can implement. So we also |
2285 // check for the interface [JavaScriptIndexingBehavior]. | 2287 // check for the interface [JavaScriptIndexingBehavior]. |
2286 ClassElement typedDataClass = compiler.commonElements.typedDataClass; | 2288 ClassElement typedDataClass = compiler.commonElements.typedDataClass; |
2287 return typedDataClass != null && | 2289 return typedDataClass != null && |
2288 compiler.world.isInstantiated(typedDataClass) && | 2290 compiler.closedWorld.isInstantiated(typedDataClass) && |
2289 mask.satisfies(typedDataClass, compiler.world) && | 2291 mask.satisfies(typedDataClass, compiler.closedWorld) && |
2290 mask.satisfies(helpers.jsIndexingBehaviorInterface, compiler.world); | 2292 mask.satisfies( |
| 2293 helpers.jsIndexingBehaviorInterface, compiler.closedWorld); |
2291 } | 2294 } |
2292 | 2295 |
2293 bool couldBeTypedArray(TypeMask mask) { | 2296 bool couldBeTypedArray(TypeMask mask) { |
2294 bool intersects(TypeMask type1, TypeMask type2) => | 2297 bool intersects(TypeMask type1, TypeMask type2) => |
2295 !type1.intersection(type2, compiler.world).isEmpty; | 2298 !type1.intersection(type2, compiler.closedWorld).isEmpty; |
2296 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and | 2299 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and |
2297 // jsIndexingBehaviourInterface. | 2300 // jsIndexingBehaviourInterface. |
2298 ClassElement typedDataClass = compiler.commonElements.typedDataClass; | 2301 ClassElement typedDataClass = compiler.commonElements.typedDataClass; |
2299 return typedDataClass != null && | 2302 return typedDataClass != null && |
2300 compiler.world.isInstantiated(typedDataClass) && | 2303 compiler.closedWorld.isInstantiated(typedDataClass) && |
2301 intersects( | 2304 intersects( |
2302 mask, new TypeMask.subtype(typedDataClass, compiler.world)) && | 2305 mask, new TypeMask.subtype(typedDataClass, compiler.closedWorld)) && |
2303 intersects( | 2306 intersects( |
2304 mask, | 2307 mask, |
2305 new TypeMask.subtype( | 2308 new TypeMask.subtype( |
2306 helpers.jsIndexingBehaviorInterface, compiler.world)); | 2309 helpers.jsIndexingBehaviorInterface, compiler.closedWorld)); |
2307 } | 2310 } |
2308 | 2311 |
2309 /// Returns all static fields that are referenced through [targetsUsed]. | 2312 /// Returns all static fields that are referenced through [targetsUsed]. |
2310 /// If the target is a library or class all nested static fields are | 2313 /// If the target is a library or class all nested static fields are |
2311 /// included too. | 2314 /// included too. |
2312 Iterable<Element> _findStaticFieldTargets() { | 2315 Iterable<Element> _findStaticFieldTargets() { |
2313 List staticFields = []; | 2316 List staticFields = []; |
2314 | 2317 |
2315 void addFieldsInContainer(ScopeContainerElement container) { | 2318 void addFieldsInContainer(ScopeContainerElement container) { |
2316 container.forEachLocalMember((Element member) { | 2319 container.forEachLocalMember((Element member) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 !element.isFactoryConstructor) { | 2501 !element.isFactoryConstructor) { |
2499 reporter.internalError( | 2502 reporter.internalError( |
2500 element, | 2503 element, |
2501 "@NoThrows() is currently limited to top-level" | 2504 "@NoThrows() is currently limited to top-level" |
2502 " or static functions and factory constructors."); | 2505 " or static functions and factory constructors."); |
2503 } | 2506 } |
2504 if (VERBOSE_OPTIMIZER_HINTS) { | 2507 if (VERBOSE_OPTIMIZER_HINTS) { |
2505 reporter.reportHintMessage( | 2508 reporter.reportHintMessage( |
2506 element, MessageKind.GENERIC, {'text': "Cannot throw"}); | 2509 element, MessageKind.GENERIC, {'text': "Cannot throw"}); |
2507 } | 2510 } |
2508 compiler.world.registerCannotThrow(element); | 2511 compiler.inferenceWorld.registerCannotThrow(element); |
2509 } else if (cls == helpers.noSideEffectsClass) { | 2512 } else if (cls == helpers.noSideEffectsClass) { |
2510 hasNoSideEffects = true; | 2513 hasNoSideEffects = true; |
2511 if (VERBOSE_OPTIMIZER_HINTS) { | 2514 if (VERBOSE_OPTIMIZER_HINTS) { |
2512 reporter.reportHintMessage( | 2515 reporter.reportHintMessage( |
2513 element, MessageKind.GENERIC, {'text': "Has no side effects"}); | 2516 element, MessageKind.GENERIC, {'text': "Has no side effects"}); |
2514 } | 2517 } |
2515 compiler.world.registerSideEffectsFree(element); | 2518 compiler.inferenceWorld.registerSideEffectsFree(element); |
2516 } | 2519 } |
2517 } | 2520 } |
2518 if (hasForceInline && hasNoInline) { | 2521 if (hasForceInline && hasNoInline) { |
2519 reporter.internalError( | 2522 reporter.internalError( |
2520 element, "@ForceInline() must not be used with @NoInline."); | 2523 element, "@ForceInline() must not be used with @NoInline."); |
2521 } | 2524 } |
2522 if (hasNoThrows && !hasNoInline) { | 2525 if (hasNoThrows && !hasNoInline) { |
2523 reporter.internalError( | 2526 reporter.internalError( |
2524 element, "@NoThrows() should always be combined with @NoInline."); | 2527 element, "@NoThrows() should always be combined with @NoInline."); |
2525 } | 2528 } |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 if (backend.compiler.options.enableTypeAssertions) { | 2865 if (backend.compiler.options.enableTypeAssertions) { |
2863 onIsCheck(type, transformed); | 2866 onIsCheck(type, transformed); |
2864 } | 2867 } |
2865 break; | 2868 break; |
2866 case TypeUseKind.CATCH_TYPE: | 2869 case TypeUseKind.CATCH_TYPE: |
2867 onIsCheck(type, transformed); | 2870 onIsCheck(type, transformed); |
2868 break; | 2871 break; |
2869 case TypeUseKind.TYPE_LITERAL: | 2872 case TypeUseKind.TYPE_LITERAL: |
2870 backend.customElementsAnalysis.registerTypeLiteral(type); | 2873 backend.customElementsAnalysis.registerTypeLiteral(type); |
2871 if (type.isTypedef) { | 2874 if (type.isTypedef) { |
2872 backend.compiler.world.allTypedefs.add(type.element); | 2875 backend.compiler.openWorld.allTypedefs.add(type.element); |
2873 } | 2876 } |
2874 if (type.isTypeVariable && type is! MethodTypeVariableType) { | 2877 if (type.isTypeVariable && type is! MethodTypeVariableType) { |
2875 // GENERIC_METHODS: The `is!` test above filters away method type | 2878 // GENERIC_METHODS: The `is!` test above filters away method type |
2876 // variables, because they have the value `dynamic` with the | 2879 // variables, because they have the value `dynamic` with the |
2877 // incomplete support for generic methods offered with | 2880 // incomplete support for generic methods offered with |
2878 // '--generic-method-syntax'. This must be revised in order to | 2881 // '--generic-method-syntax'. This must be revised in order to |
2879 // support generic methods fully. | 2882 // support generic methods fully. |
2880 ClassElement cls = type.element.enclosingClass; | 2883 ClassElement cls = type.element.enclosingClass; |
2881 backend.rti.registerClassUsingTypeVariableExpression(cls); | 2884 backend.rti.registerClassUsingTypeVariableExpression(cls); |
2882 registerBackendImpact(transformed, impacts.typeVariableExpression); | 2885 registerBackendImpact(transformed, impacts.typeVariableExpression); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3195 | 3198 |
3196 @override | 3199 @override |
3197 void onImpactUsed(ImpactUseCase impactUse) { | 3200 void onImpactUsed(ImpactUseCase impactUse) { |
3198 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { | 3201 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { |
3199 // TODO(johnniwinther): Allow emptying when serialization has been | 3202 // TODO(johnniwinther): Allow emptying when serialization has been |
3200 // performed. | 3203 // performed. |
3201 resolution.emptyCache(); | 3204 resolution.emptyCache(); |
3202 } | 3205 } |
3203 } | 3206 } |
3204 } | 3207 } |
OLD | NEW |