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 |
11 import '../closure.dart'; | 11 import '../closure.dart'; |
12 import '../common.dart'; | 12 import '../common.dart'; |
13 import '../common/backend_api.dart' | 13 import '../common/backend_api.dart' |
14 show | 14 show |
15 Backend, | 15 Backend, |
16 BackendClasses, | 16 BackendClasses, |
17 ImpactTransformer, | 17 ImpactTransformer, |
18 ForeignResolver, | 18 ForeignResolver, |
19 NativeRegistry; | 19 NativeRegistry; |
20 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 20 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
21 import '../common/names.dart' show Identifiers, Selectors, Uris; | 21 import '../common/names.dart' show Identifiers, Uris; |
22 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; | 22 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; |
23 import '../common/tasks.dart' show CompilerTask; | 23 import '../common/tasks.dart' show CompilerTask; |
24 import '../compiler.dart' show Compiler; | 24 import '../compiler.dart' show Compiler; |
25 import '../constants/constant_system.dart'; | 25 import '../constants/constant_system.dart'; |
26 import '../constants/expressions.dart'; | 26 import '../constants/expressions.dart'; |
27 import '../constants/values.dart'; | 27 import '../constants/values.dart'; |
28 import '../core_types.dart' show CoreClasses, CoreTypes; | 28 import '../core_types.dart' show CommonElements, CoreClasses, CoreTypes; |
29 import '../dart_types.dart'; | 29 import '../dart_types.dart'; |
30 import '../deferred_load.dart' show DeferredLoadTask; | 30 import '../deferred_load.dart' show DeferredLoadTask; |
31 import '../dump_info.dart' show DumpInfoTask; | 31 import '../dump_info.dart' show DumpInfoTask; |
32 import '../elements/elements.dart'; | 32 import '../elements/elements.dart'; |
33 import '../elements/entities.dart'; | 33 import '../elements/entities.dart'; |
34 import '../enqueue.dart' | 34 import '../enqueue.dart' |
35 show Enqueuer, ResolutionEnqueuer, TreeShakingEnqueuerStrategy; | 35 show Enqueuer, ResolutionEnqueuer, TreeShakingEnqueuerStrategy; |
36 import '../io/position_information.dart' show PositionSourceInformationStrategy; | 36 import '../io/position_information.dart' show PositionSourceInformationStrategy; |
37 import '../io/source_information.dart' show SourceInformationStrategy; | 37 import '../io/source_information.dart' show SourceInformationStrategy; |
38 import '../io/start_end_information.dart' | 38 import '../io/start_end_information.dart' |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 functionCompiler = | 590 functionCompiler = |
591 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); | 591 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); |
592 serialization = new JavaScriptBackendSerialization(this); | 592 serialization = new JavaScriptBackendSerialization(this); |
593 backendClasses = new JavaScriptBackendClasses(helpers); | 593 backendClasses = new JavaScriptBackendClasses(helpers); |
594 } | 594 } |
595 | 595 |
596 ConstantSystem get constantSystem => constants.constantSystem; | 596 ConstantSystem get constantSystem => constants.constantSystem; |
597 | 597 |
598 DiagnosticReporter get reporter => compiler.reporter; | 598 DiagnosticReporter get reporter => compiler.reporter; |
599 | 599 |
| 600 CommonElements get commonElements => compiler.commonElements; |
| 601 |
600 CoreClasses get coreClasses => compiler.coreClasses; | 602 CoreClasses get coreClasses => compiler.coreClasses; |
601 | 603 |
602 CoreTypes get coreTypes => compiler.coreTypes; | 604 CoreTypes get coreTypes => compiler.coreTypes; |
603 | 605 |
604 Resolution get resolution => compiler.resolution; | 606 Resolution get resolution => compiler.resolution; |
605 | 607 |
606 /// Returns constant environment for the JavaScript interpretation of the | 608 /// Returns constant environment for the JavaScript interpretation of the |
607 /// constants. | 609 /// constants. |
608 JavaScriptConstantCompiler get constants { | 610 JavaScriptConstantCompiler get constants { |
609 return constantCompilerTask.jsConstantCompiler; | 611 return constantCompilerTask.jsConstantCompiler; |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 if (TRACE_CALLS) { | 1277 if (TRACE_CALLS) { |
1276 impactTransformer.registerBackendImpact( | 1278 impactTransformer.registerBackendImpact( |
1277 impactBuilder, impacts.traceHelper); | 1279 impactBuilder, impacts.traceHelper); |
1278 } | 1280 } |
1279 impactTransformer.registerBackendImpact( | 1281 impactTransformer.registerBackendImpact( |
1280 impactBuilder, impacts.assertUnreachable); | 1282 impactBuilder, impacts.assertUnreachable); |
1281 _registerCheckedModeHelpers(impactBuilder); | 1283 _registerCheckedModeHelpers(impactBuilder); |
1282 return impactBuilder; | 1284 return impactBuilder; |
1283 } | 1285 } |
1284 | 1286 |
1285 onResolutionComplete(ClosedWorldRefiner closedWorldRefiner) { | 1287 onResolutionComplete( |
| 1288 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { |
1286 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { | 1289 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { |
1287 processAnnotations(entity, closedWorldRefiner); | 1290 processAnnotations(entity, closedWorldRefiner); |
1288 } | 1291 } |
1289 super.onResolutionComplete(closedWorldRefiner); | 1292 computeMembersNeededForReflection(closedWorld); |
1290 computeMembersNeededForReflection(); | 1293 rti.computeClassesNeedingRti( |
1291 rti.computeClassesNeedingRti(); | 1294 compiler.enqueuer.resolution.universe, closedWorld); |
1292 _registeredMetadata.clear(); | 1295 _registeredMetadata.clear(); |
1293 } | 1296 } |
1294 | 1297 |
1295 onTypeInferenceComplete() { | 1298 onTypeInferenceComplete() { |
1296 super.onTypeInferenceComplete(); | 1299 super.onTypeInferenceComplete(); |
1297 noSuchMethodRegistry.onTypeInferenceComplete(); | 1300 noSuchMethodRegistry.onTypeInferenceComplete(); |
1298 } | 1301 } |
1299 | 1302 |
1300 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, | 1303 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, |
1301 {bool forResolution}) { | 1304 {bool forResolution}) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 element == coreClasses.boolClass) { | 1650 element == coreClasses.boolClass) { |
1648 if (nativeCheckOnly) return null; | 1651 if (nativeCheckOnly) return null; |
1649 return typeCast ? 'boolTypeCast' : 'boolTypeCheck'; | 1652 return typeCast ? 'boolTypeCast' : 'boolTypeCheck'; |
1650 } else if (element == helpers.jsIntClass || | 1653 } else if (element == helpers.jsIntClass || |
1651 element == coreClasses.intClass || | 1654 element == coreClasses.intClass || |
1652 element == helpers.jsUInt32Class || | 1655 element == helpers.jsUInt32Class || |
1653 element == helpers.jsUInt31Class || | 1656 element == helpers.jsUInt31Class || |
1654 element == helpers.jsPositiveIntClass) { | 1657 element == helpers.jsPositiveIntClass) { |
1655 if (nativeCheckOnly) return null; | 1658 if (nativeCheckOnly) return null; |
1656 return typeCast ? 'intTypeCast' : 'intTypeCheck'; | 1659 return typeCast ? 'intTypeCast' : 'intTypeCheck'; |
1657 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { | 1660 } else if (Elements.isNumberOrStringSupertype(element, commonElements)) { |
1658 if (nativeCheck) { | 1661 if (nativeCheck) { |
1659 return typeCast | 1662 return typeCast |
1660 ? 'numberOrStringSuperNativeTypeCast' | 1663 ? 'numberOrStringSuperNativeTypeCast' |
1661 : 'numberOrStringSuperNativeTypeCheck'; | 1664 : 'numberOrStringSuperNativeTypeCheck'; |
1662 } else { | 1665 } else { |
1663 return typeCast | 1666 return typeCast |
1664 ? 'numberOrStringSuperTypeCast' | 1667 ? 'numberOrStringSuperTypeCast' |
1665 : 'numberOrStringSuperTypeCheck'; | 1668 : 'numberOrStringSuperTypeCheck'; |
1666 } | 1669 } |
1667 } else if (Elements.isStringOnlySupertype(element, compiler)) { | 1670 } else if (Elements.isStringOnlySupertype(element, commonElements)) { |
1668 if (nativeCheck) { | 1671 if (nativeCheck) { |
1669 return typeCast | 1672 return typeCast |
1670 ? 'stringSuperNativeTypeCast' | 1673 ? 'stringSuperNativeTypeCast' |
1671 : 'stringSuperNativeTypeCheck'; | 1674 : 'stringSuperNativeTypeCheck'; |
1672 } else { | 1675 } else { |
1673 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; | 1676 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; |
1674 } | 1677 } |
1675 } else if ((element == coreClasses.listClass || | 1678 } else if ((element == coreClasses.listClass || |
1676 element == helpers.jsArrayClass) && | 1679 element == helpers.jsArrayClass) && |
1677 type.treatAsRaw) { | 1680 type.treatAsRaw) { |
1678 if (nativeCheckOnly) return null; | 1681 if (nativeCheckOnly) return null; |
1679 return typeCast ? 'listTypeCast' : 'listTypeCheck'; | 1682 return typeCast ? 'listTypeCast' : 'listTypeCheck'; |
1680 } else { | 1683 } else { |
1681 if (Elements.isListSupertype(element, compiler)) { | 1684 if (Elements.isListSupertype(element, commonElements)) { |
1682 if (nativeCheck) { | 1685 if (nativeCheck) { |
1683 return typeCast | 1686 return typeCast |
1684 ? 'listSuperNativeTypeCast' | 1687 ? 'listSuperNativeTypeCast' |
1685 : 'listSuperNativeTypeCheck'; | 1688 : 'listSuperNativeTypeCheck'; |
1686 } else { | 1689 } else { |
1687 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck'; | 1690 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck'; |
1688 } | 1691 } |
1689 } else { | 1692 } else { |
1690 if (type.isInterfaceType && !type.treatAsRaw) { | 1693 if (type.isInterfaceType && !type.treatAsRaw) { |
1691 return typeCast ? 'subtypeCast' : 'assertSubtype'; | 1694 return typeCast ? 'subtypeCast' : 'assertSubtype'; |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2018 * reflection. | 2021 * reflection. |
2019 * | 2022 * |
2020 * We have to precompute this set as we cannot easily answer the need for | 2023 * We have to precompute this set as we cannot easily answer the need for |
2021 * reflection locally when looking at the member: We lack the information by | 2024 * reflection locally when looking at the member: We lack the information by |
2022 * which classes a member is inherited. Called after resolution is complete. | 2025 * which classes a member is inherited. Called after resolution is complete. |
2023 * | 2026 * |
2024 * We filter out private libraries here, as their elements should not | 2027 * We filter out private libraries here, as their elements should not |
2025 * be visible by reflection unless some other interfaces makes them | 2028 * be visible by reflection unless some other interfaces makes them |
2026 * accessible. | 2029 * accessible. |
2027 */ | 2030 */ |
2028 void computeMembersNeededForReflection() { | 2031 void computeMembersNeededForReflection(ClosedWorld closedWorld) { |
2029 if (_membersNeededForReflection != null) return; | 2032 if (_membersNeededForReflection != null) return; |
2030 if (compiler.commonElements.mirrorsLibrary == null) { | 2033 if (closedWorld.commonElements.mirrorsLibrary == null) { |
2031 _membersNeededForReflection = const ImmutableEmptySet<Element>(); | 2034 _membersNeededForReflection = const ImmutableEmptySet<Element>(); |
2032 return; | 2035 return; |
2033 } | 2036 } |
2034 // Compute a mapping from class to the closures it contains, so we | 2037 // Compute a mapping from class to the closures it contains, so we |
2035 // can include the correct ones when including the class. | 2038 // can include the correct ones when including the class. |
2036 Map<ClassElement, List<LocalFunctionElement>> closureMap = | 2039 Map<ClassElement, List<LocalFunctionElement>> closureMap = |
2037 new Map<ClassElement, List<LocalFunctionElement>>(); | 2040 new Map<ClassElement, List<LocalFunctionElement>>(); |
2038 for (LocalFunctionElement closure in compiler.resolverWorld.allClosures) { | 2041 for (LocalFunctionElement closure in compiler.resolverWorld.allClosures) { |
2039 closureMap.putIfAbsent(closure.enclosingClass, () => []).add(closure); | 2042 closureMap.putIfAbsent(closure.enclosingClass, () => []).add(closure); |
2040 } | 2043 } |
(...skipping 21 matching lines...) Expand all Loading... |
2062 memberNames.add(member.name); | 2065 memberNames.add(member.name); |
2063 reflectableMembers.add(element); | 2066 reflectableMembers.add(element); |
2064 element.nestedClosures | 2067 element.nestedClosures |
2065 .forEach((SynthesizedCallMethodElementX callFunction) { | 2068 .forEach((SynthesizedCallMethodElementX callFunction) { |
2066 reflectableMembers.add(callFunction); | 2069 reflectableMembers.add(callFunction); |
2067 reflectableMembers.add(callFunction.closureClass); | 2070 reflectableMembers.add(callFunction.closureClass); |
2068 }); | 2071 }); |
2069 } | 2072 } |
2070 }); | 2073 }); |
2071 // 4) all overriding members of subclasses/subtypes (should be resolved) | 2074 // 4) all overriding members of subclasses/subtypes (should be resolved) |
2072 if (compiler.closedWorld.hasAnyStrictSubtype(cls)) { | 2075 if (closedWorld.hasAnyStrictSubtype(cls)) { |
2073 compiler.closedWorld.forEachStrictSubtypeOf(cls, | 2076 closedWorld.forEachStrictSubtypeOf(cls, (ClassElement subcls) { |
2074 (ClassElement subcls) { | |
2075 subcls.forEachClassMember((Member member) { | 2077 subcls.forEachClassMember((Member member) { |
2076 if (memberNames.contains(member.name)) { | 2078 if (memberNames.contains(member.name)) { |
2077 // TODO(20993): find out why this assertion fails. | 2079 // TODO(20993): find out why this assertion fails. |
2078 // assert(invariant(member.element, | 2080 // assert(invariant(member.element, |
2079 // resolution.hasBeenProcessed(member.element))); | 2081 // resolution.hasBeenProcessed(member.element))); |
2080 if (resolution.hasBeenProcessed(member.element)) { | 2082 if (resolution.hasBeenProcessed(member.element)) { |
2081 reflectableMembers.add(member.element); | 2083 reflectableMembers.add(member.element); |
2082 } | 2084 } |
2083 } | 2085 } |
2084 }); | 2086 }); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 // As we do not think about closures as classes, yet, we have to make sure | 2145 // As we do not think about closures as classes, yet, we have to make sure |
2144 // their superclasses are available for reflection manually. | 2146 // their superclasses are available for reflection manually. |
2145 if (foundClosure) { | 2147 if (foundClosure) { |
2146 reflectableMembers.add(helpers.closureClass); | 2148 reflectableMembers.add(helpers.closureClass); |
2147 } | 2149 } |
2148 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; | 2150 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; |
2149 if (closurizedMembers.any(reflectableMembers.contains)) { | 2151 if (closurizedMembers.any(reflectableMembers.contains)) { |
2150 reflectableMembers.add(helpers.boundClosureClass); | 2152 reflectableMembers.add(helpers.boundClosureClass); |
2151 } | 2153 } |
2152 // Add typedefs. | 2154 // Add typedefs. |
2153 reflectableMembers.addAll( | 2155 reflectableMembers |
2154 compiler.closedWorld.allTypedefs.where(referencedFromMirrorSystem)); | 2156 .addAll(closedWorld.allTypedefs.where(referencedFromMirrorSystem)); |
2155 // Register all symbols of reflectable elements | 2157 // Register all symbols of reflectable elements |
2156 for (Element element in reflectableMembers) { | 2158 for (Element element in reflectableMembers) { |
2157 symbolsUsed.add(element.name); | 2159 symbolsUsed.add(element.name); |
2158 } | 2160 } |
2159 _membersNeededForReflection = reflectableMembers; | 2161 _membersNeededForReflection = reflectableMembers; |
2160 } | 2162 } |
2161 | 2163 |
2162 // TODO(20791): compute closure classes after resolution and move this code to | 2164 // TODO(20791): compute closure classes after resolution and move this code to |
2163 // [computeMembersNeededForReflection]. | 2165 // [computeMembersNeededForReflection]. |
2164 void maybeMarkClosureAsNeededForReflection( | 2166 void maybeMarkClosureAsNeededForReflection( |
(...skipping 16 matching lines...) Expand all Loading... |
2181 // chance of making the dispatch record access monomorphic. | 2183 // chance of making the dispatch record access monomorphic. |
2182 jsAst.PropertyAccess record = | 2184 jsAst.PropertyAccess record = |
2183 new jsAst.PropertyAccess(use2, dispatchProperty); | 2185 new jsAst.PropertyAccess(use2, dispatchProperty); |
2184 | 2186 |
2185 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; | 2187 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; |
2186 FunctionElement helper = helpers.isJsIndexable; | 2188 FunctionElement helper = helpers.isJsIndexable; |
2187 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); | 2189 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); |
2188 return new jsAst.Call(helperExpression, arguments); | 2190 return new jsAst.Call(helperExpression, arguments); |
2189 } | 2191 } |
2190 | 2192 |
2191 bool isTypedArray(TypeMask mask) { | |
2192 // Just checking for [:TypedData:] is not sufficient, as it is an | |
2193 // abstract class any user-defined class can implement. So we also | |
2194 // check for the interface [JavaScriptIndexingBehavior]. | |
2195 ClassElement typedDataClass = compiler.commonElements.typedDataClass; | |
2196 return typedDataClass != null && | |
2197 compiler.closedWorld.isInstantiated(typedDataClass) && | |
2198 mask.satisfies(typedDataClass, compiler.closedWorld) && | |
2199 mask.satisfies( | |
2200 helpers.jsIndexingBehaviorInterface, compiler.closedWorld); | |
2201 } | |
2202 | |
2203 bool couldBeTypedArray(TypeMask mask) { | |
2204 bool intersects(TypeMask type1, TypeMask type2) => | |
2205 !type1.intersection(type2, compiler.closedWorld).isEmpty; | |
2206 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and | |
2207 // jsIndexingBehaviourInterface. | |
2208 ClassElement typedDataClass = compiler.commonElements.typedDataClass; | |
2209 return typedDataClass != null && | |
2210 compiler.closedWorld.isInstantiated(typedDataClass) && | |
2211 intersects( | |
2212 mask, new TypeMask.subtype(typedDataClass, compiler.closedWorld)) && | |
2213 intersects( | |
2214 mask, | |
2215 new TypeMask.subtype( | |
2216 helpers.jsIndexingBehaviorInterface, compiler.closedWorld)); | |
2217 } | |
2218 | |
2219 /// Returns all static fields that are referenced through [targetsUsed]. | 2193 /// Returns all static fields that are referenced through [targetsUsed]. |
2220 /// If the target is a library or class all nested static fields are | 2194 /// If the target is a library or class all nested static fields are |
2221 /// included too. | 2195 /// included too. |
2222 Iterable<Element> _findStaticFieldTargets() { | 2196 Iterable<Element> _findStaticFieldTargets() { |
2223 List staticFields = []; | 2197 List staticFields = []; |
2224 | 2198 |
2225 void addFieldsInContainer(ScopeContainerElement container) { | 2199 void addFieldsInContainer(ScopeContainerElement container) { |
2226 container.forEachLocalMember((Element member) { | 2200 container.forEachLocalMember((Element member) { |
2227 if (!member.isInstanceMember && member.isField) { | 2201 if (!member.isInstanceMember && member.isField) { |
2228 staticFields.add(member); | 2202 staticFields.add(member); |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3223 ClassElement get typeImplementation => helpers.typeLiteralClass; | 3197 ClassElement get typeImplementation => helpers.typeLiteralClass; |
3224 ClassElement get boolImplementation => helpers.jsBoolClass; | 3198 ClassElement get boolImplementation => helpers.jsBoolClass; |
3225 ClassElement get nullImplementation => helpers.jsNullClass; | 3199 ClassElement get nullImplementation => helpers.jsNullClass; |
3226 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; | 3200 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; |
3227 ClassElement get asyncFutureImplementation => helpers.futureImplementation; | 3201 ClassElement get asyncFutureImplementation => helpers.futureImplementation; |
3228 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; | 3202 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; |
3229 ClassElement get functionImplementation => helpers.coreClasses.functionClass; | 3203 ClassElement get functionImplementation => helpers.coreClasses.functionClass; |
3230 ClassElement get indexableImplementation => helpers.jsIndexableClass; | 3204 ClassElement get indexableImplementation => helpers.jsIndexableClass; |
3231 ClassElement get mutableIndexableImplementation => | 3205 ClassElement get mutableIndexableImplementation => |
3232 helpers.jsMutableIndexableClass; | 3206 helpers.jsMutableIndexableClass; |
| 3207 ClassElement get indexingBehaviorImplementation => |
| 3208 helpers.jsIndexingBehaviorInterface; |
3233 | 3209 |
3234 bool isDefaultEqualityImplementation(Element element) { | 3210 bool isDefaultEqualityImplementation(Element element) { |
3235 assert(element.name == '=='); | 3211 assert(element.name == '=='); |
3236 ClassElement classElement = element.enclosingClass; | 3212 ClassElement classElement = element.enclosingClass; |
3237 return classElement == helpers.coreClasses.objectClass || | 3213 return classElement == helpers.coreClasses.objectClass || |
3238 classElement == helpers.jsInterceptorClass || | 3214 classElement == helpers.jsInterceptorClass || |
3239 classElement == helpers.jsNullClass; | 3215 classElement == helpers.jsNullClass; |
3240 } | 3216 } |
| 3217 |
| 3218 @override |
| 3219 bool isInterceptorClass(ClassElement cls) { |
| 3220 return helpers.backend.isInterceptorClass(cls); |
| 3221 } |
| 3222 |
| 3223 @override |
| 3224 bool isNative(Element element) { |
| 3225 return helpers.backend.isNative(element); |
| 3226 } |
3241 } | 3227 } |
OLD | NEW |