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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 328 |
329 FunctionInlineCache inlineCache = new FunctionInlineCache(); | 329 FunctionInlineCache inlineCache = new FunctionInlineCache(); |
330 | 330 |
331 /// If [true], the compiler will emit code that logs whenever a method is | 331 /// If [true], the compiler will emit code that logs whenever a method is |
332 /// called. When TRACE_METHOD is 'console' this will be logged | 332 /// called. When TRACE_METHOD is 'console' this will be logged |
333 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the | 333 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the |
334 /// information will be sent to a server via a POST request. | 334 /// information will be sent to a server via a POST request. |
335 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); | 335 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); |
336 static const bool TRACE_CALLS = | 336 static const bool TRACE_CALLS = |
337 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; | 337 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; |
338 MethodElement traceHelper; | |
339 | 338 |
340 TypeMask get stringType => compiler.closedWorld.commonMasks.stringType; | 339 TypeMask get stringType => compiler.closedWorld.commonMasks.stringType; |
341 TypeMask get doubleType => compiler.closedWorld.commonMasks.doubleType; | 340 TypeMask get doubleType => compiler.closedWorld.commonMasks.doubleType; |
342 TypeMask get intType => compiler.closedWorld.commonMasks.intType; | 341 TypeMask get intType => compiler.closedWorld.commonMasks.intType; |
343 TypeMask get uint32Type => compiler.closedWorld.commonMasks.uint32Type; | 342 TypeMask get uint32Type => compiler.closedWorld.commonMasks.uint32Type; |
344 TypeMask get uint31Type => compiler.closedWorld.commonMasks.uint31Type; | 343 TypeMask get uint31Type => compiler.closedWorld.commonMasks.uint31Type; |
345 TypeMask get positiveIntType => | 344 TypeMask get positiveIntType => |
346 compiler.closedWorld.commonMasks.positiveIntType; | 345 compiler.closedWorld.commonMasks.positiveIntType; |
347 TypeMask get numType => compiler.closedWorld.commonMasks.numType; | 346 TypeMask get numType => compiler.closedWorld.commonMasks.numType; |
348 TypeMask get boolType => compiler.closedWorld.commonMasks.boolType; | 347 TypeMask get boolType => compiler.closedWorld.commonMasks.boolType; |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 // differences. | 1028 // differences. |
1030 assert(invariant(interceptorMember, | 1029 assert(invariant(interceptorMember, |
1031 interceptorMember.enclosingClass == interceptorClass, | 1030 interceptorMember.enclosingClass == interceptorClass, |
1032 message: | 1031 message: |
1033 "Member ${member.name} not overridden in ${interceptorClass}. " | 1032 "Member ${member.name} not overridden in ${interceptorClass}. " |
1034 "Found $interceptorMember from " | 1033 "Found $interceptorMember from " |
1035 "${interceptorMember.enclosingClass}.")); | 1034 "${interceptorMember.enclosingClass}.")); |
1036 }); | 1035 }); |
1037 } | 1036 } |
1038 | 1037 |
1039 void addInterceptorsForNativeClassMembers( | 1038 void addInterceptorsForNativeClassMembers(ClassElement cls, |
1040 ClassElement cls, Enqueuer enqueuer) { | 1039 {bool forResolution}) { |
1041 if (enqueuer.isResolutionQueue) { | 1040 if (forResolution) { |
1042 cls.ensureResolved(resolution); | 1041 cls.ensureResolved(resolution); |
1043 cls.forEachMember((ClassElement classElement, Element member) { | 1042 cls.forEachMember((ClassElement classElement, Element member) { |
1044 if (member.name == Identifiers.call) { | 1043 if (member.name == Identifiers.call) { |
1045 return; | 1044 return; |
1046 } | 1045 } |
1047 if (member.isSynthesized) return; | 1046 if (member.isSynthesized) return; |
1048 // All methods on [Object] are shadowed by [Interceptor]. | 1047 // All methods on [Object] are shadowed by [Interceptor]. |
1049 if (classElement == coreClasses.objectClass) return; | 1048 if (classElement == coreClasses.objectClass) return; |
1050 Set<Element> set = interceptedElements.putIfAbsent( | 1049 Set<Element> set = interceptedElements.putIfAbsent( |
1051 member.name, () => new Set<Element>()); | 1050 member.name, () => new Set<Element>()); |
1052 set.add(member); | 1051 set.add(member); |
1053 }, includeSuperAndInjectedMembers: true); | 1052 }, includeSuperAndInjectedMembers: true); |
1054 | 1053 |
1055 // Walk superclass chain to find mixins. | 1054 // Walk superclass chain to find mixins. |
1056 for (; cls != null; cls = cls.superclass) { | 1055 for (; cls != null; cls = cls.superclass) { |
1057 if (cls.isMixinApplication) { | 1056 if (cls.isMixinApplication) { |
1058 MixinApplicationElement mixinApplication = cls; | 1057 MixinApplicationElement mixinApplication = cls; |
1059 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); | 1058 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); |
1060 } | 1059 } |
1061 } | 1060 } |
1062 } | 1061 } |
1063 } | 1062 } |
1064 | 1063 |
1065 void addInterceptors(ClassElement cls, Enqueuer enqueuer) { | 1064 void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder, |
1066 if (enqueuer.isResolutionQueue) { | 1065 {bool forResolution}) { |
| 1066 if (forResolution) { |
| 1067 if (_interceptedClasses.add(cls)) { |
| 1068 cls.ensureResolved(resolution); |
| 1069 cls.forEachMember((ClassElement classElement, Element member) { |
| 1070 // All methods on [Object] are shadowed by [Interceptor]. |
| 1071 if (classElement == coreClasses.objectClass) return; |
| 1072 Set<Element> set = interceptedElements.putIfAbsent( |
| 1073 member.name, () => new Set<Element>()); |
| 1074 set.add(member); |
| 1075 }, includeSuperAndInjectedMembers: true); |
| 1076 } |
1067 _interceptedClasses.add(helpers.jsInterceptorClass); | 1077 _interceptedClasses.add(helpers.jsInterceptorClass); |
1068 _interceptedClasses.add(cls); | |
1069 cls.ensureResolved(resolution); | |
1070 cls.forEachMember((ClassElement classElement, Element member) { | |
1071 // All methods on [Object] are shadowed by [Interceptor]. | |
1072 if (classElement == coreClasses.objectClass) return; | |
1073 Set<Element> set = interceptedElements.putIfAbsent( | |
1074 member.name, () => new Set<Element>()); | |
1075 set.add(member); | |
1076 }, includeSuperAndInjectedMembers: true); | |
1077 } | 1078 } |
1078 enqueueClass(enqueuer, cls); | 1079 impactTransformer.registerBackendInstantiation(impactBuilder, cls); |
1079 } | 1080 } |
1080 | 1081 |
1081 Set<ClassElement> get interceptedClasses { | 1082 Set<ClassElement> get interceptedClasses { |
1082 assert(compiler.enqueuer.resolution.queueIsClosed); | 1083 assert(compiler.enqueuer.resolution.queueIsClosed); |
1083 return _interceptedClasses; | 1084 return _interceptedClasses; |
1084 } | 1085 } |
1085 | 1086 |
1086 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 1087 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
1087 jsAst.Name name = namer.nameForGetInterceptor(classes); | 1088 jsAst.Name name = namer.nameForGetInterceptor(classes); |
1088 if (classes.contains(helpers.jsInterceptorClass)) { | 1089 if (classes.contains(helpers.jsInterceptorClass)) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 // constant emitter will generate a call to the createRuntimeType | 1162 // constant emitter will generate a call to the createRuntimeType |
1162 // helper so we register a use of that. | 1163 // helper so we register a use of that. |
1163 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1164 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1164 // TODO(johnniwinther): Find the right [CallStructure]. | 1165 // TODO(johnniwinther): Find the right [CallStructure]. |
1165 helpers.createRuntimeType, | 1166 helpers.createRuntimeType, |
1166 null)); | 1167 null)); |
1167 } | 1168 } |
1168 } | 1169 } |
1169 } | 1170 } |
1170 | 1171 |
1171 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { | 1172 WorldImpact registerInstantiatedClass(ClassElement cls, |
1172 _processClass(cls, enqueuer); | 1173 {bool forResolution}) { |
| 1174 return _processClass(cls, forResolution: forResolution); |
1173 } | 1175 } |
1174 | 1176 |
1175 void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) { | 1177 WorldImpact registerImplementedClass(ClassElement cls, {bool forResolution}) { |
1176 _processClass(cls, enqueuer); | 1178 return _processClass(cls, forResolution: forResolution); |
1177 } | 1179 } |
1178 | 1180 |
1179 void _processClass(ClassElement cls, Enqueuer enqueuer) { | 1181 WorldImpact _processClass(ClassElement cls, {bool forResolution}) { |
| 1182 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
1180 if (!cls.typeVariables.isEmpty) { | 1183 if (!cls.typeVariables.isEmpty) { |
1181 typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer); | 1184 typeVariableHandler.registerClassWithTypeVariables(cls, |
| 1185 forResolution: forResolution); |
1182 } | 1186 } |
1183 | 1187 |
1184 // Register any helper that will be needed by the backend. | 1188 // Register any helper that will be needed by the backend. |
1185 if (enqueuer.isResolutionQueue) { | 1189 if (forResolution) { |
1186 if (cls == coreClasses.intClass || | 1190 if (cls == coreClasses.intClass || |
1187 cls == coreClasses.doubleClass || | 1191 cls == coreClasses.doubleClass || |
1188 cls == coreClasses.numClass) { | 1192 cls == coreClasses.numClass) { |
1189 // The backend will try to optimize number operations and use the | 1193 impactTransformer.registerBackendImpact( |
1190 // `iae` helper directly. | 1194 impactBuilder, impacts.numClasses); |
1191 enqueue(enqueuer, helpers.throwIllegalArgumentException); | |
1192 } else if (cls == coreClasses.listClass || | 1195 } else if (cls == coreClasses.listClass || |
1193 cls == coreClasses.stringClass) { | 1196 cls == coreClasses.stringClass) { |
1194 // The backend will try to optimize array and string access and use the | 1197 impactTransformer.registerBackendImpact( |
1195 // `ioore` and `iae` helpers directly. | 1198 impactBuilder, impacts.listOrStringClasses); |
1196 enqueue(enqueuer, helpers.throwIndexOutOfRangeException); | |
1197 enqueue(enqueuer, helpers.throwIllegalArgumentException); | |
1198 } else if (cls == coreClasses.functionClass) { | 1199 } else if (cls == coreClasses.functionClass) { |
1199 enqueueClass(enqueuer, helpers.closureClass); | 1200 impactTransformer.registerBackendImpact( |
| 1201 impactBuilder, impacts.functionClass); |
1200 } else if (cls == coreClasses.mapClass) { | 1202 } else if (cls == coreClasses.mapClass) { |
1201 // The backend will use a literal list to initialize the entries | 1203 impactTransformer.registerBackendImpact( |
1202 // of the map. | 1204 impactBuilder, impacts.mapClass); |
1203 enqueueClass(enqueuer, coreClasses.listClass); | |
1204 enqueueClass(enqueuer, helpers.mapLiteralClass); | |
1205 // For map literals, the dependency between the implementation class | 1205 // For map literals, the dependency between the implementation class |
1206 // and [Map] is not visible, so we have to add it manually. | 1206 // and [Map] is not visible, so we have to add it manually. |
1207 rti.registerRtiDependency(helpers.mapLiteralClass, cls); | 1207 rti.registerRtiDependency(helpers.mapLiteralClass, cls); |
1208 } else if (cls == helpers.boundClosureClass) { | 1208 } else if (cls == helpers.boundClosureClass) { |
1209 // TODO(johnniwinther): Is this a noop? | 1209 impactTransformer.registerBackendImpact( |
1210 enqueueClass(enqueuer, helpers.boundClosureClass); | 1210 impactBuilder, impacts.boundClosureClass); |
1211 } else if (isNativeOrExtendsNative(cls)) { | 1211 } else if (isNativeOrExtendsNative(cls)) { |
1212 enqueue(enqueuer, helpers.getNativeInterceptorMethod); | 1212 impactTransformer.registerBackendImpact( |
1213 enqueueClass(enqueuer, helpers.jsInterceptorClass); | 1213 impactBuilder, impacts.nativeOrExtendsClass); |
1214 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass); | |
1215 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass); | |
1216 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass); | |
1217 } else if (cls == helpers.mapLiteralClass) { | 1214 } else if (cls == helpers.mapLiteralClass) { |
1218 // For map literals, the dependency between the implementation class | 1215 impactTransformer.registerBackendImpact( |
1219 // and [Map] is not visible, so we have to add it manually. | 1216 impactBuilder, impacts.mapLiteralClass); |
1220 Element getFactory(String name, int arity) { | |
1221 // The constructor is on the patch class, but dart2js unit tests don't | |
1222 // have a patch class. | |
1223 ClassElement implementation = cls.implementation; | |
1224 ConstructorElement ctor = implementation.lookupConstructor(name); | |
1225 if (ctor == null || | |
1226 (Name.isPrivateName(name) && | |
1227 ctor.library != helpers.mapLiteralClass.library)) { | |
1228 reporter.internalError( | |
1229 helpers.mapLiteralClass, | |
1230 "Map literal class ${helpers.mapLiteralClass} missing " | |
1231 "'$name' constructor" | |
1232 " ${helpers.mapLiteralClass.constructors}"); | |
1233 } | |
1234 return ctor; | |
1235 } | |
1236 | |
1237 Element getMember(String name) { | |
1238 // The constructor is on the patch class, but dart2js unit tests don't | |
1239 // have a patch class. | |
1240 ClassElement implementation = cls.implementation; | |
1241 Element element = implementation.lookupLocalMember(name); | |
1242 if (element == null || !element.isFunction || !element.isStatic) { | |
1243 reporter.internalError( | |
1244 helpers.mapLiteralClass, | |
1245 "Map literal class ${helpers.mapLiteralClass} missing " | |
1246 "'$name' static member function"); | |
1247 } | |
1248 return element; | |
1249 } | |
1250 | |
1251 helpers.mapLiteralConstructor = getFactory('_literal', 1); | |
1252 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); | |
1253 enqueue(enqueuer, helpers.mapLiteralConstructor); | |
1254 enqueue(enqueuer, helpers.mapLiteralConstructorEmpty); | |
1255 | |
1256 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral'); | |
1257 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); | |
1258 enqueue(enqueuer, helpers.mapLiteralUntypedMaker); | |
1259 enqueue(enqueuer, helpers.mapLiteralUntypedEmptyMaker); | |
1260 } | 1217 } |
1261 } | 1218 } |
1262 if (cls == helpers.closureClass) { | 1219 if (cls == helpers.closureClass) { |
1263 enqueue(enqueuer, helpers.closureFromTearOff); | 1220 impactTransformer.registerBackendImpact( |
| 1221 impactBuilder, impacts.closureClass); |
1264 } | 1222 } |
1265 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { | 1223 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { |
1266 addInterceptors(helpers.jsStringClass, enqueuer); | 1224 addInterceptors(helpers.jsStringClass, impactBuilder, |
| 1225 forResolution: forResolution); |
1267 } else if (cls == coreClasses.listClass || | 1226 } else if (cls == coreClasses.listClass || |
1268 cls == helpers.jsArrayClass || | 1227 cls == helpers.jsArrayClass || |
1269 cls == helpers.jsFixedArrayClass || | 1228 cls == helpers.jsFixedArrayClass || |
1270 cls == helpers.jsExtendableArrayClass || | 1229 cls == helpers.jsExtendableArrayClass || |
1271 cls == helpers.jsUnmodifiableArrayClass) { | 1230 cls == helpers.jsUnmodifiableArrayClass) { |
1272 addInterceptors(helpers.jsArrayClass, enqueuer); | 1231 addInterceptors(helpers.jsArrayClass, impactBuilder, |
1273 addInterceptors(helpers.jsMutableArrayClass, enqueuer); | 1232 forResolution: forResolution); |
1274 addInterceptors(helpers.jsFixedArrayClass, enqueuer); | 1233 addInterceptors(helpers.jsMutableArrayClass, impactBuilder, |
1275 addInterceptors(helpers.jsExtendableArrayClass, enqueuer); | 1234 forResolution: forResolution); |
1276 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer); | 1235 addInterceptors(helpers.jsFixedArrayClass, impactBuilder, |
1277 if (enqueuer.isResolutionQueue) { | 1236 forResolution: forResolution); |
1278 // Literal lists can be translated into calls to these functions: | 1237 addInterceptors(helpers.jsExtendableArrayClass, impactBuilder, |
1279 enqueue(enqueuer, helpers.jsArrayTypedConstructor); | 1238 forResolution: forResolution); |
1280 enqueue(enqueuer, helpers.setRuntimeTypeInfo); | 1239 addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder, |
1281 enqueue(enqueuer, helpers.getTypeArgumentByIndex); | 1240 forResolution: forResolution); |
| 1241 if (forResolution) { |
| 1242 impactTransformer.registerBackendImpact( |
| 1243 impactBuilder, impacts.listClasses); |
1282 } | 1244 } |
1283 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { | 1245 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { |
1284 addInterceptors(helpers.jsIntClass, enqueuer); | 1246 addInterceptors(helpers.jsIntClass, impactBuilder, |
1285 addInterceptors(helpers.jsPositiveIntClass, enqueuer); | 1247 forResolution: forResolution); |
1286 addInterceptors(helpers.jsUInt32Class, enqueuer); | 1248 addInterceptors(helpers.jsPositiveIntClass, impactBuilder, |
1287 addInterceptors(helpers.jsUInt31Class, enqueuer); | 1249 forResolution: forResolution); |
1288 addInterceptors(helpers.jsNumberClass, enqueuer); | 1250 addInterceptors(helpers.jsUInt32Class, impactBuilder, |
| 1251 forResolution: forResolution); |
| 1252 addInterceptors(helpers.jsUInt31Class, impactBuilder, |
| 1253 forResolution: forResolution); |
| 1254 addInterceptors(helpers.jsNumberClass, impactBuilder, |
| 1255 forResolution: forResolution); |
1289 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { | 1256 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { |
1290 addInterceptors(helpers.jsDoubleClass, enqueuer); | 1257 addInterceptors(helpers.jsDoubleClass, impactBuilder, |
1291 addInterceptors(helpers.jsNumberClass, enqueuer); | 1258 forResolution: forResolution); |
| 1259 addInterceptors(helpers.jsNumberClass, impactBuilder, |
| 1260 forResolution: forResolution); |
1292 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { | 1261 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { |
1293 addInterceptors(helpers.jsBoolClass, enqueuer); | 1262 addInterceptors(helpers.jsBoolClass, impactBuilder, |
| 1263 forResolution: forResolution); |
1294 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { | 1264 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { |
1295 addInterceptors(helpers.jsNullClass, enqueuer); | 1265 addInterceptors(helpers.jsNullClass, impactBuilder, |
| 1266 forResolution: forResolution); |
1296 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { | 1267 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { |
1297 addInterceptors(helpers.jsIntClass, enqueuer); | 1268 addInterceptors(helpers.jsIntClass, impactBuilder, |
1298 addInterceptors(helpers.jsPositiveIntClass, enqueuer); | 1269 forResolution: forResolution); |
1299 addInterceptors(helpers.jsUInt32Class, enqueuer); | 1270 addInterceptors(helpers.jsPositiveIntClass, impactBuilder, |
1300 addInterceptors(helpers.jsUInt31Class, enqueuer); | 1271 forResolution: forResolution); |
1301 addInterceptors(helpers.jsDoubleClass, enqueuer); | 1272 addInterceptors(helpers.jsUInt32Class, impactBuilder, |
1302 addInterceptors(helpers.jsNumberClass, enqueuer); | 1273 forResolution: forResolution); |
| 1274 addInterceptors(helpers.jsUInt31Class, impactBuilder, |
| 1275 forResolution: forResolution); |
| 1276 addInterceptors(helpers.jsDoubleClass, impactBuilder, |
| 1277 forResolution: forResolution); |
| 1278 addInterceptors(helpers.jsNumberClass, impactBuilder, |
| 1279 forResolution: forResolution); |
1303 } else if (cls == helpers.jsJavaScriptObjectClass) { | 1280 } else if (cls == helpers.jsJavaScriptObjectClass) { |
1304 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer); | 1281 addInterceptors(helpers.jsJavaScriptObjectClass, impactBuilder, |
| 1282 forResolution: forResolution); |
1305 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { | 1283 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { |
1306 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer); | 1284 addInterceptors(helpers.jsPlainJavaScriptObjectClass, impactBuilder, |
| 1285 forResolution: forResolution); |
1307 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { | 1286 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { |
1308 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer); | 1287 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder, |
| 1288 forResolution: forResolution); |
1309 } else if (cls == helpers.jsJavaScriptFunctionClass) { | 1289 } else if (cls == helpers.jsJavaScriptFunctionClass) { |
1310 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer); | 1290 addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder, |
| 1291 forResolution: forResolution); |
1311 } else if (isNativeOrExtendsNative(cls)) { | 1292 } else if (isNativeOrExtendsNative(cls)) { |
1312 addInterceptorsForNativeClassMembers(cls, enqueuer); | 1293 addInterceptorsForNativeClassMembers(cls, forResolution: forResolution); |
1313 } else if (cls == helpers.jsIndexingBehaviorInterface) { | 1294 } else if (cls == helpers.jsIndexingBehaviorInterface) { |
1314 // These two helpers are used by the emitter and the codegen. | 1295 impactTransformer.registerBackendImpact( |
1315 // Because we cannot enqueue elements at the time of emission, | 1296 impactBuilder, impacts.jsIndexingBehavior); |
1316 // we make sure they are always generated. | |
1317 enqueue(enqueuer, helpers.isJsIndexable); | |
1318 } | 1297 } |
1319 | 1298 |
1320 customElementsAnalysis.registerInstantiatedClass(cls, | 1299 customElementsAnalysis.registerInstantiatedClass(cls, |
1321 forResolution: enqueuer.isResolutionQueue); | 1300 forResolution: forResolution); |
1322 if (!enqueuer.isResolutionQueue) { | 1301 if (!forResolution) { |
1323 lookupMapAnalysis.registerInstantiatedClass(cls); | 1302 lookupMapAnalysis.registerInstantiatedClass(cls); |
1324 } | 1303 } |
| 1304 |
| 1305 return impactBuilder; |
1325 } | 1306 } |
1326 | 1307 |
1327 void registerInstantiatedType(InterfaceType type) { | 1308 void registerInstantiatedType(InterfaceType type) { |
1328 lookupMapAnalysis.registerInstantiatedType(type); | 1309 lookupMapAnalysis.registerInstantiatedType(type); |
1329 } | 1310 } |
1330 | 1311 |
1331 void enqueueHelpers(ResolutionEnqueuer enqueuer) { | 1312 @override |
| 1313 WorldImpact computeHelpersImpact() { |
1332 assert(helpers.interceptorsLibrary != null); | 1314 assert(helpers.interceptorsLibrary != null); |
| 1315 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
1333 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1316 // TODO(ngeoffray): Not enqueuing those two classes currently make |
1334 // the compiler potentially crash. However, any reasonable program | 1317 // the compiler potentially crash. However, any reasonable program |
1335 // will instantiate those two classes. | 1318 // will instantiate those two classes. |
1336 addInterceptors(helpers.jsBoolClass, enqueuer); | 1319 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true); |
1337 addInterceptors(helpers.jsNullClass, enqueuer); | 1320 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true); |
1338 if (compiler.options.enableTypeAssertions) { | 1321 if (compiler.options.enableTypeAssertions) { |
1339 // Unconditionally register the helper that checks if the | 1322 impactTransformer.registerBackendImpact( |
1340 // expression in an if/while/for is a boolean. | 1323 impactBuilder, impacts.enableTypeAssertions); |
1341 // TODO(ngeoffray): Should we have the resolver register those instead? | |
1342 Element e = helpers.boolConversionCheck; | |
1343 if (e != null) enqueue(enqueuer, e); | |
1344 } | 1324 } |
1345 | 1325 |
1346 if (TRACE_CALLS) { | 1326 if (TRACE_CALLS) { |
1347 traceHelper = TRACE_METHOD == 'console' | 1327 impactTransformer.registerBackendImpact( |
1348 ? helpers.consoleTraceHelper | 1328 impactBuilder, impacts.traceHelper); |
1349 : helpers.postTraceHelper; | |
1350 assert(traceHelper != null); | |
1351 enqueue(enqueuer, traceHelper); | |
1352 } | 1329 } |
1353 enqueue(enqueuer, helpers.assertUnreachableMethod); | 1330 impactTransformer.registerBackendImpact( |
1354 registerCheckedModeHelpers(enqueuer); | 1331 impactBuilder, impacts.assertUnreachable); |
| 1332 _registerCheckedModeHelpers(impactBuilder); |
| 1333 return impactBuilder; |
1355 } | 1334 } |
1356 | 1335 |
1357 onResolutionComplete() { | 1336 onResolutionComplete() { |
1358 super.onResolutionComplete(); | 1337 super.onResolutionComplete(); |
1359 computeMembersNeededForReflection(); | 1338 computeMembersNeededForReflection(); |
1360 rti.computeClassesNeedingRti(); | 1339 rti.computeClassesNeedingRti(); |
1361 _registeredMetadata.clear(); | 1340 _registeredMetadata.clear(); |
1362 } | 1341 } |
1363 | 1342 |
1364 onTypeInferenceComplete() { | 1343 onTypeInferenceComplete() { |
1365 super.onTypeInferenceComplete(); | 1344 super.onTypeInferenceComplete(); |
1366 noSuchMethodRegistry.onTypeInferenceComplete(); | 1345 noSuchMethodRegistry.onTypeInferenceComplete(); |
1367 } | 1346 } |
1368 | 1347 |
1369 void registerGetRuntimeTypeArgument() { | 1348 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, |
1370 enqueueImpact(compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument); | 1349 {bool forResolution}) { |
| 1350 if (forResolution || methodNeedsRti(callMethod)) { |
| 1351 return _registerComputeSignature(); |
| 1352 } |
| 1353 return const WorldImpact(); |
1371 } | 1354 } |
1372 | 1355 |
1373 void registerCallMethodWithFreeTypeVariables( | 1356 WorldImpact registerClosureWithFreeTypeVariables(Element closure, |
1374 Element callMethod, Enqueuer enqueuer) { | 1357 {bool forResolution}) { |
1375 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { | 1358 if (forResolution || methodNeedsRti(closure)) { |
1376 registerComputeSignature(enqueuer); | 1359 return _registerComputeSignature(); |
1377 } | 1360 } |
| 1361 return const WorldImpact(); |
1378 } | 1362 } |
1379 | 1363 |
1380 void registerClosureWithFreeTypeVariables( | 1364 WorldImpact registerBoundClosure() { |
1381 Element closure, Enqueuer enqueuer) { | 1365 return impactTransformer.createImpactFor(impacts.memberClosure); |
1382 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { | |
1383 registerComputeSignature(enqueuer); | |
1384 } | |
1385 } | 1366 } |
1386 | 1367 |
1387 void registerBoundClosure(Enqueuer enqueuer) { | 1368 WorldImpact registerGetOfStaticFunction() { |
1388 helpers.boundClosureClass.ensureResolved(resolution); | 1369 return impactTransformer.createImpactFor(impacts.staticClosure); |
1389 enqueuer.registerInstantiatedType(helpers.boundClosureClass.rawType); | |
1390 } | 1370 } |
1391 | 1371 |
1392 void registerGetOfStaticFunction(Enqueuer enqueuer) { | 1372 WorldImpact _registerComputeSignature() { |
1393 helpers.closureClass.ensureResolved(resolution); | |
1394 enqueuer.registerInstantiatedType(helpers.closureClass.rawType); | |
1395 } | |
1396 | |
1397 void registerComputeSignature(Enqueuer enqueuer) { | |
1398 // Calls to [:computeSignature:] are generated by the emitter and we | 1373 // Calls to [:computeSignature:] are generated by the emitter and we |
1399 // therefore need to enqueue the used elements in the codegen enqueuer as | 1374 // therefore need to enqueue the used elements in the codegen enqueuer as |
1400 // well as in the resolution enqueuer. | 1375 // well as in the resolution enqueuer. |
1401 enqueueImpact(enqueuer, impacts.computeSignature); | 1376 return impactTransformer.createImpactFor(impacts.computeSignature); |
1402 } | 1377 } |
1403 | 1378 |
1404 void registerRuntimeType(ResolutionEnqueuer enqueuer) { | 1379 WorldImpact registerRuntimeType() { |
1405 registerComputeSignature(enqueuer); | 1380 return impactTransformer.createImpactFor(impacts.runtimeTypeSupport); |
1406 enqueue(enqueuer, helpers.setRuntimeTypeInfo); | |
1407 registerGetRuntimeTypeArgument(); | |
1408 enqueue(enqueuer, helpers.getRuntimeTypeInfo); | |
1409 enqueueClass(enqueuer, coreClasses.listClass); | |
1410 } | 1381 } |
1411 | 1382 |
1412 void registerTypeVariableBoundsSubtypeCheck( | 1383 void registerTypeVariableBoundsSubtypeCheck( |
1413 DartType typeArgument, DartType bound) { | 1384 DartType typeArgument, DartType bound) { |
1414 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1385 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
1415 } | 1386 } |
1416 | 1387 |
1417 void registerCheckDeferredIsLoaded(ResolutionEnqueuer enqueuer) { | 1388 WorldImpact computeDeferredLoadingImpact() { |
1418 enqueue(enqueuer, helpers.checkDeferredIsLoaded); | 1389 return impactTransformer.createImpactFor(impacts.deferredLoading); |
1419 // Also register the types of the arguments passed to this method. | |
1420 enqueueClass(enqueuer, coreClasses.stringClass); | |
1421 } | 1390 } |
1422 | 1391 |
1423 void registerNoSuchMethod(FunctionElement noSuchMethod) { | 1392 void registerNoSuchMethod(FunctionElement noSuchMethod) { |
1424 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); | 1393 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); |
1425 } | 1394 } |
1426 | 1395 |
1427 /// Called when resolving a call to a foreign function. | 1396 /// Called when resolving a call to a foreign function. |
1428 native.NativeBehavior resolveForeignCall(Send node, Element element, | 1397 native.NativeBehavior resolveForeignCall(Send node, Element element, |
1429 CallStructure callStructure, ForeignResolver resolver) { | 1398 CallStructure callStructure, ForeignResolver resolver) { |
1430 native.NativeResolutionEnqueuer nativeEnqueuer = | 1399 native.NativeResolutionEnqueuer nativeEnqueuer = |
(...skipping 20 matching lines...) Expand all Loading... |
1451 } | 1420 } |
1452 } | 1421 } |
1453 } | 1422 } |
1454 reporter.reportErrorMessage( | 1423 reporter.reportErrorMessage( |
1455 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 1424 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
1456 } | 1425 } |
1457 // No native behavior for this call. | 1426 // No native behavior for this call. |
1458 return null; | 1427 return null; |
1459 } | 1428 } |
1460 | 1429 |
1461 void enableNoSuchMethod(Enqueuer world) { | 1430 WorldImpact enableNoSuchMethod() { |
1462 enqueue(world, helpers.createInvocationMirror); | 1431 return impactTransformer.createImpactFor(impacts.noSuchMethodSupport); |
1463 world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null)); | |
1464 } | 1432 } |
1465 | 1433 |
1466 void enableIsolateSupport(Enqueuer enqueuer) { | 1434 WorldImpact enableIsolateSupport({bool forResolution}) { |
| 1435 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
1467 // TODO(floitsch): We should also ensure that the class IsolateMessage is | 1436 // TODO(floitsch): We should also ensure that the class IsolateMessage is |
1468 // instantiated. Currently, just enabling isolate support works. | 1437 // instantiated. Currently, just enabling isolate support works. |
1469 if (compiler.mainFunction != null) { | 1438 if (compiler.mainFunction != null) { |
1470 // The JavaScript backend implements [Isolate.spawn] by looking up | 1439 // The JavaScript backend implements [Isolate.spawn] by looking up |
1471 // top-level functions by name. So all top-level function tear-off | 1440 // top-level functions by name. So all top-level function tear-off |
1472 // closures have a private name field. | 1441 // closures have a private name field. |
1473 // | 1442 // |
1474 // The JavaScript backend of [Isolate.spawnUri] uses the same internal | 1443 // The JavaScript backend of [Isolate.spawnUri] uses the same internal |
1475 // implementation as [Isolate.spawn], and fails if it cannot look main up | 1444 // implementation as [Isolate.spawn], and fails if it cannot look main up |
1476 // by name. | 1445 // by name. |
1477 enqueuer.registerStaticUse( | 1446 impactBuilder.registerStaticUse( |
1478 new StaticUse.staticTearOff(compiler.mainFunction)); | 1447 new StaticUse.staticTearOff(compiler.mainFunction)); |
1479 } | 1448 } |
1480 if (enqueuer.isResolutionQueue) { | 1449 impactTransformer.registerBackendImpact( |
1481 void enqueue(Element element) { | 1450 impactBuilder, impacts.isolateSupport); |
1482 enqueuer.addToWorkList(element); | 1451 if (forResolution) { |
1483 compiler.globalDependencies.registerDependency(element); | 1452 impactTransformer.registerBackendImpact( |
1484 helpersUsed.add(element.declaration); | 1453 impactBuilder, impacts.isolateSupportForResolution); |
1485 } | |
1486 | |
1487 enqueue(helpers.startRootIsolate); | |
1488 enqueue(helpers.currentIsolate); | |
1489 enqueue(helpers.callInIsolate); | |
1490 } else { | |
1491 enqueuer.addToWorkList(helpers.startRootIsolate); | |
1492 } | 1454 } |
| 1455 return impactBuilder; |
1493 } | 1456 } |
1494 | 1457 |
1495 bool classNeedsRti(ClassElement cls) { | 1458 bool classNeedsRti(ClassElement cls) { |
1496 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; | 1459 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; |
1497 return rti.classesNeedingRti.contains(cls.declaration); | 1460 return rti.classesNeedingRti.contains(cls.declaration); |
1498 } | 1461 } |
1499 | 1462 |
1500 bool classNeedsRtiField(ClassElement cls) { | 1463 bool classNeedsRtiField(ClassElement cls) { |
1501 if (cls.rawType.typeArguments.isEmpty) return false; | 1464 if (cls.rawType.typeArguments.isEmpty) return false; |
1502 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; | 1465 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; |
1503 return rti.classesNeedingRti.contains(cls.declaration); | 1466 return rti.classesNeedingRti.contains(cls.declaration); |
1504 } | 1467 } |
1505 | 1468 |
1506 bool isComplexNoSuchMethod(FunctionElement element) => | 1469 bool isComplexNoSuchMethod(FunctionElement element) => |
1507 noSuchMethodRegistry.isComplex(element); | 1470 noSuchMethodRegistry.isComplex(element); |
1508 | 1471 |
1509 bool isDefaultEqualityImplementation(Element element) { | 1472 bool isDefaultEqualityImplementation(Element element) { |
1510 assert(element.name == '=='); | 1473 assert(element.name == '=='); |
1511 ClassElement classElement = element.enclosingClass; | 1474 ClassElement classElement = element.enclosingClass; |
1512 return classElement == coreClasses.objectClass || | 1475 return classElement == coreClasses.objectClass || |
1513 classElement == helpers.jsInterceptorClass || | 1476 classElement == helpers.jsInterceptorClass || |
1514 classElement == helpers.jsNullClass; | 1477 classElement == helpers.jsNullClass; |
1515 } | 1478 } |
1516 | 1479 |
1517 bool methodNeedsRti(FunctionElement function) { | 1480 bool methodNeedsRti(FunctionElement function) { |
1518 return rti.methodsNeedingRti.contains(function) || | 1481 return rti.methodsNeedingRti.contains(function) || |
1519 compiler.resolverWorld.hasRuntimeTypeSupport; | 1482 compiler.resolverWorld.hasRuntimeTypeSupport; |
1520 } | 1483 } |
1521 | 1484 |
1522 /// Enqueue [e] in [enqueuer]. | |
1523 /// | |
1524 /// This method calls [registerBackendUse]. | |
1525 void enqueue(Enqueuer enqueuer, Element e) { | |
1526 if (e == null) return; | |
1527 registerBackendUse(e); | |
1528 enqueuer.addToWorkList(e); | |
1529 compiler.globalDependencies.registerDependency(e); | |
1530 } | |
1531 | |
1532 /// Register instantiation of [cls] in [enqueuer]. | |
1533 /// | |
1534 /// This method calls [registerBackendUse]. | |
1535 void enqueueClass(Enqueuer enqueuer, ClassElement cls) { | |
1536 if (cls == null) return; | |
1537 registerBackendUse(cls); | |
1538 helpersUsed.add(cls.declaration); | |
1539 if (cls.declaration != cls.implementation) { | |
1540 helpersUsed.add(cls.implementation); | |
1541 } | |
1542 cls.ensureResolved(resolution); | |
1543 enqueuer.registerInstantiatedType(cls.rawType); | |
1544 } | |
1545 | |
1546 /// Register instantiation of [type] in [enqueuer]. | |
1547 /// | |
1548 /// This method calls [registerBackendUse]. | |
1549 void enqueueType(Enqueuer enqueuer, InterfaceType type) { | |
1550 if (type == null) return; | |
1551 ClassElement cls = type.element; | |
1552 registerBackendUse(cls); | |
1553 helpersUsed.add(cls.declaration); | |
1554 if (cls.declaration != cls.implementation) { | |
1555 helpersUsed.add(cls.implementation); | |
1556 } | |
1557 cls.ensureResolved(resolution); | |
1558 enqueuer.registerInstantiatedType(type); | |
1559 } | |
1560 | |
1561 void enqueueImpact(Enqueuer enqueuer, BackendImpact impact) { | |
1562 for (Element staticUse in impact.staticUses) { | |
1563 enqueue(enqueuer, staticUse); | |
1564 } | |
1565 for (InterfaceType type in impact.instantiatedTypes) { | |
1566 enqueueType(enqueuer, type); | |
1567 } | |
1568 for (ClassElement cls in impact.instantiatedClasses) { | |
1569 enqueueClass(enqueuer, cls); | |
1570 } | |
1571 for (BackendImpact otherImpact in impact.otherImpacts) { | |
1572 enqueueImpact(enqueuer, otherImpact); | |
1573 } | |
1574 } | |
1575 | |
1576 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; | 1485 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; |
1577 | 1486 |
1578 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { | 1487 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { |
1579 return new CodegenEnqueuer( | 1488 return new CodegenEnqueuer( |
1580 task, compiler, const TreeShakingEnqueuerStrategy()); | 1489 task, compiler, const TreeShakingEnqueuerStrategy()); |
1581 } | 1490 } |
1582 | 1491 |
1583 WorldImpact codegen(CodegenWorkItem work) { | 1492 WorldImpact codegen(CodegenWorkItem work) { |
1584 Element element = work.element; | 1493 Element element = work.element; |
1585 if (compiler.elementHasCompileTimeError(element)) { | 1494 if (compiler.elementHasCompileTimeError(element)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 constant.isImplicit || | 1536 constant.isImplicit || |
1628 constant.isPotential, | 1537 constant.isPotential, |
1629 message: "Constant expression without value: " | 1538 message: "Constant expression without value: " |
1630 "${constant.toStructuredText()}.")); | 1539 "${constant.toStructuredText()}.")); |
1631 } | 1540 } |
1632 } else { | 1541 } else { |
1633 // If the constant-handler was not able to produce a result we have to | 1542 // If the constant-handler was not able to produce a result we have to |
1634 // go through the builder (below) to generate the lazy initializer for | 1543 // go through the builder (below) to generate the lazy initializer for |
1635 // the static variable. | 1544 // the static variable. |
1636 // We also need to register the use of the cyclic-error helper. | 1545 // We also need to register the use of the cyclic-error helper. |
1637 compiler.enqueuer.codegen.registerStaticUse(new StaticUse.staticInvoke( | 1546 work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke( |
1638 helpers.cyclicThrowHelper, CallStructure.ONE_ARG)); | 1547 helpers.cyclicThrowHelper, CallStructure.ONE_ARG)); |
1639 } | 1548 } |
1640 } | 1549 } |
1641 | 1550 |
1642 jsAst.Fun function = functionCompiler.compile(work); | 1551 jsAst.Fun function = functionCompiler.compile(work); |
1643 if (function.sourceInformation == null) { | 1552 if (function.sourceInformation == null) { |
1644 function = function.withSourceInformation( | 1553 function = function.withSourceInformation( |
1645 sourceInformationStrategy.buildSourceMappedMarker()); | 1554 sourceInformationStrategy.buildSourceMappedMarker()); |
1646 } | 1555 } |
1647 generatedCode[element] = function; | 1556 generatedCode[element] = function; |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 // interceptors? | 1758 // interceptors? |
1850 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; | 1759 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; |
1851 } else { | 1760 } else { |
1852 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; | 1761 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; |
1853 } | 1762 } |
1854 } | 1763 } |
1855 } | 1764 } |
1856 } | 1765 } |
1857 } | 1766 } |
1858 | 1767 |
1859 void registerCheckedModeHelpers(ResolutionEnqueuer enqueuer) { | 1768 void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) { |
1860 // We register all the helpers in the resolution queue. | 1769 // We register all the helpers in the resolution queue. |
1861 // TODO(13155): Find a way to register fewer helpers. | 1770 // TODO(13155): Find a way to register fewer helpers. |
| 1771 List<Element> staticUses = <Element>[]; |
1862 for (CheckedModeHelper helper in checkedModeHelpers) { | 1772 for (CheckedModeHelper helper in checkedModeHelpers) { |
1863 enqueue(enqueuer, helper.getStaticUse(compiler).element); | 1773 staticUses.add(helper.getStaticUse(compiler).element); |
1864 } | 1774 } |
| 1775 impactTransformer.registerBackendImpact( |
| 1776 impactBuilder, new BackendImpact(globalUses: staticUses)); |
1865 } | 1777 } |
1866 | 1778 |
1867 /** | 1779 /** |
1868 * Returns [:true:] if the checking of [type] is performed directly on the | 1780 * Returns [:true:] if the checking of [type] is performed directly on the |
1869 * object and not on an interceptor. | 1781 * object and not on an interceptor. |
1870 */ | 1782 */ |
1871 bool hasDirectCheckFor(DartType type) { | 1783 bool hasDirectCheckFor(DartType type) { |
1872 Element element = type.element; | 1784 Element element = type.element; |
1873 return element == coreClasses.stringClass || | 1785 return element == coreClasses.stringClass || |
1874 element == coreClasses.boolClass || | 1786 element == coreClasses.boolClass || |
(...skipping 10 matching lines...) Expand all Loading... |
1885 bool mayGenerateInstanceofCheck(DartType type) { | 1797 bool mayGenerateInstanceofCheck(DartType type) { |
1886 // We can use an instanceof check for raw types that have no subclass that | 1798 // We can use an instanceof check for raw types that have no subclass that |
1887 // is mixed-in or in an implements clause. | 1799 // is mixed-in or in an implements clause. |
1888 | 1800 |
1889 if (!type.isRaw) return false; | 1801 if (!type.isRaw) return false; |
1890 ClassElement classElement = type.element; | 1802 ClassElement classElement = type.element; |
1891 if (isInterceptorClass(classElement)) return false; | 1803 if (isInterceptorClass(classElement)) return false; |
1892 return compiler.closedWorld.hasOnlySubclasses(classElement); | 1804 return compiler.closedWorld.hasOnlySubclasses(classElement); |
1893 } | 1805 } |
1894 | 1806 |
1895 void registerStaticUse(Enqueuer enqueuer, Element element) { | 1807 WorldImpact registerStaticUse(Element element, {bool forResolution}) { |
| 1808 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); |
1896 if (element == helpers.disableTreeShakingMarker) { | 1809 if (element == helpers.disableTreeShakingMarker) { |
1897 isTreeShakingDisabled = true; | 1810 isTreeShakingDisabled = true; |
1898 } else if (element == helpers.preserveNamesMarker) { | 1811 } else if (element == helpers.preserveNamesMarker) { |
1899 mustPreserveNames = true; | 1812 mustPreserveNames = true; |
1900 } else if (element == helpers.preserveMetadataMarker) { | 1813 } else if (element == helpers.preserveMetadataMarker) { |
1901 mustRetainMetadata = true; | 1814 mustRetainMetadata = true; |
1902 } else if (element == helpers.preserveUrisMarker) { | 1815 } else if (element == helpers.preserveUrisMarker) { |
1903 if (compiler.options.preserveUris) mustPreserveUris = true; | 1816 if (compiler.options.preserveUris) mustPreserveUris = true; |
1904 } else if (element == helpers.preserveLibraryNamesMarker) { | 1817 } else if (element == helpers.preserveLibraryNamesMarker) { |
1905 mustRetainLibraryNames = true; | 1818 mustRetainLibraryNames = true; |
1906 } else if (element == helpers.getIsolateAffinityTagMarker) { | 1819 } else if (element == helpers.getIsolateAffinityTagMarker) { |
1907 needToInitializeIsolateAffinityTag = true; | 1820 needToInitializeIsolateAffinityTag = true; |
1908 } else if (element.isDeferredLoaderGetter) { | 1821 } else if (element.isDeferredLoaderGetter) { |
1909 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1822 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
1910 if (!isLoadLibraryFunctionResolved) { | 1823 if (!isLoadLibraryFunctionResolved) { |
1911 isLoadLibraryFunctionResolved = true; | 1824 isLoadLibraryFunctionResolved = true; |
1912 if (enqueuer.isResolutionQueue) { | 1825 if (forResolution) { |
1913 enqueue(enqueuer, helpers.loadLibraryWrapper); | 1826 impactTransformer.registerBackendImpact( |
| 1827 worldImpact, impacts.loadLibrary); |
1914 } | 1828 } |
1915 } | 1829 } |
1916 } else if (element == helpers.requiresPreambleMarker) { | 1830 } else if (element == helpers.requiresPreambleMarker) { |
1917 requiresPreamble = true; | 1831 requiresPreamble = true; |
1918 } | 1832 } |
1919 customElementsAnalysis.registerStaticUse(element, | 1833 customElementsAnalysis.registerStaticUse(element, |
1920 forResolution: enqueuer.isResolutionQueue); | 1834 forResolution: forResolution); |
| 1835 return worldImpact; |
1921 } | 1836 } |
1922 | 1837 |
1923 /// Called when [:const Symbol(name):] is seen. | 1838 /// Called when [:const Symbol(name):] is seen. |
1924 void registerConstSymbol(String name) { | 1839 void registerConstSymbol(String name) { |
1925 symbolsUsed.add(name); | 1840 symbolsUsed.add(name); |
1926 if (name.endsWith('=')) { | 1841 if (name.endsWith('=')) { |
1927 symbolsUsed.add(name.substring(0, name.length - 1)); | 1842 symbolsUsed.add(name.substring(0, name.length - 1)); |
1928 } | 1843 } |
1929 } | 1844 } |
1930 | 1845 |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2337 return staticFields; | 2252 return staticFields; |
2338 } | 2253 } |
2339 | 2254 |
2340 /// Called when [enqueuer] is empty, but before it is closed. | 2255 /// Called when [enqueuer] is empty, but before it is closed. |
2341 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { | 2256 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
2342 // Add elements used synthetically, that is, through features rather than | 2257 // Add elements used synthetically, that is, through features rather than |
2343 // syntax, for instance custom elements. | 2258 // syntax, for instance custom elements. |
2344 // | 2259 // |
2345 // Return early if any elements are added to avoid counting the elements as | 2260 // Return early if any elements are added to avoid counting the elements as |
2346 // due to mirrors. | 2261 // due to mirrors. |
| 2262 enqueuer.applyImpact(customElementsAnalysis.flush( |
| 2263 forResolution: enqueuer.isResolutionQueue)); |
2347 enqueuer.applyImpact( | 2264 enqueuer.applyImpact( |
2348 compiler.impactStrategy, | |
2349 customElementsAnalysis.flush( | |
2350 forResolution: enqueuer.isResolutionQueue)); | |
2351 enqueuer.applyImpact(compiler.impactStrategy, | |
2352 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue)); | 2265 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue)); |
2353 enqueuer.applyImpact(compiler.impactStrategy, | 2266 enqueuer.applyImpact( |
2354 typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue)); | 2267 typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue)); |
2355 | 2268 |
2356 if (!enqueuer.queueIsEmpty) return false; | 2269 if (!enqueuer.queueIsEmpty) return false; |
2357 | 2270 |
2358 noSuchMethodRegistry.onQueueEmpty(); | 2271 noSuchMethodRegistry.onQueueEmpty(); |
2359 if (!enabledNoSuchMethod && | 2272 if (!enabledNoSuchMethod && |
2360 (noSuchMethodRegistry.hasThrowingNoSuchMethod || | 2273 (noSuchMethodRegistry.hasThrowingNoSuchMethod || |
2361 noSuchMethodRegistry.hasComplexNoSuchMethod)) { | 2274 noSuchMethodRegistry.hasComplexNoSuchMethod)) { |
2362 enableNoSuchMethod(enqueuer); | 2275 enqueuer.applyImpact(enableNoSuchMethod()); |
2363 enabledNoSuchMethod = true; | 2276 enabledNoSuchMethod = true; |
2364 } | 2277 } |
2365 | 2278 |
2366 if (compiler.options.useKernel && compiler.mainApp != null) { | 2279 if (compiler.options.useKernel && compiler.mainApp != null) { |
2367 kernelTask.buildKernelIr(); | 2280 kernelTask.buildKernelIr(); |
2368 } | 2281 } |
2369 | 2282 |
2370 if (compiler.options.hasIncrementalSupport) { | 2283 if (compiler.options.hasIncrementalSupport) { |
2371 // Always enable tear-off closures during incremental compilation. | 2284 // Always enable tear-off closures during incremental compilation. |
2372 Element e = helpers.closureFromTearOff; | 2285 Element element = helpers.closureFromTearOff; |
2373 if (e != null && !enqueuer.isProcessed(e)) { | 2286 if (element != null && !enqueuer.isProcessed(element)) { |
2374 registerBackendUse(e); | 2287 enqueuer.applyImpact( |
2375 enqueuer.addToWorkList(e); | 2288 impactTransformer.createImpactFor(impacts.closureClass)); |
2376 } | 2289 } |
2377 } | 2290 } |
2378 | 2291 |
2379 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { | 2292 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { |
2380 preMirrorsMethodCount = generatedCode.length; | 2293 preMirrorsMethodCount = generatedCode.length; |
2381 } | 2294 } |
2382 | 2295 |
2383 if (isTreeShakingDisabled) { | 2296 if (isTreeShakingDisabled) { |
2384 enqueuer.applyImpact( | 2297 enqueuer.applyImpact(mirrorsAnalysis.computeImpactForReflectiveElements( |
2385 compiler.impactStrategy, | 2298 recentClasses, |
2386 mirrorsAnalysis.computeImpactForReflectiveElements(recentClasses, | 2299 enqueuer.processedClasses, |
2387 enqueuer.processedClasses, compiler.libraryLoader.libraries, | 2300 compiler.libraryLoader.libraries, |
2388 forResolution: enqueuer.isResolutionQueue)); | 2301 forResolution: enqueuer.isResolutionQueue)); |
2389 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { | 2302 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { |
2390 // Add all static elements (not classes) that have been requested for | 2303 // Add all static elements (not classes) that have been requested for |
2391 // reflection. If there is no mirror-usage these are probably not | 2304 // reflection. If there is no mirror-usage these are probably not |
2392 // necessary, but the backend relies on them being resolved. | 2305 // necessary, but the backend relies on them being resolved. |
2393 enqueuer.applyImpact( | 2306 enqueuer.applyImpact(mirrorsAnalysis |
2394 compiler.impactStrategy, | 2307 .computeImpactForReflectiveStaticFields(_findStaticFieldTargets(), |
2395 mirrorsAnalysis.computeImpactForReflectiveStaticFields( | |
2396 _findStaticFieldTargets(), | |
2397 forResolution: enqueuer.isResolutionQueue)); | 2308 forResolution: enqueuer.isResolutionQueue)); |
2398 } | 2309 } |
2399 | 2310 |
2400 if (mustPreserveNames) reporter.log('Preserving names.'); | 2311 if (mustPreserveNames) reporter.log('Preserving names.'); |
2401 | 2312 |
2402 if (mustRetainMetadata) { | 2313 if (mustRetainMetadata) { |
2403 reporter.log('Retaining metadata.'); | 2314 reporter.log('Retaining metadata.'); |
2404 | 2315 |
2405 compiler.libraryLoader.libraries.forEach(retainMetadataOf); | 2316 compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
2406 | 2317 |
(...skipping 16 matching lines...) Expand all Loading... |
2423 // elements and process these instead. | 2334 // elements and process these instead. |
2424 processMetadata(compiler.enqueuer.resolution.processedElements, | 2335 processMetadata(compiler.enqueuer.resolution.processedElements, |
2425 registerMetadataConstant); | 2336 registerMetadataConstant); |
2426 } else { | 2337 } else { |
2427 for (Dependency dependency in metadataConstants) { | 2338 for (Dependency dependency in metadataConstants) { |
2428 computeImpactForCompileTimeConstant( | 2339 computeImpactForCompileTimeConstant( |
2429 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); | 2340 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
2430 } | 2341 } |
2431 metadataConstants.clear(); | 2342 metadataConstants.clear(); |
2432 } | 2343 } |
2433 enqueuer.applyImpact(compiler.impactStrategy, impactBuilder.flush()); | 2344 enqueuer.applyImpact(impactBuilder.flush()); |
2434 } | 2345 } |
2435 return true; | 2346 return true; |
2436 } | 2347 } |
2437 | 2348 |
2438 /// Call [registerMetadataConstant] on all metadata from [elements]. | 2349 /// Call [registerMetadataConstant] on all metadata from [elements]. |
2439 void processMetadata(Iterable<Element> elements, | 2350 void processMetadata(Iterable<Element> elements, |
2440 void onMetadata(MetadataAnnotation metadata)) { | 2351 void onMetadata(MetadataAnnotation metadata)) { |
2441 void processLibraryMetadata(LibraryElement library) { | 2352 void processLibraryMetadata(LibraryElement library) { |
2442 if (_registeredMetadata.add(library)) { | 2353 if (_registeredMetadata.add(library)) { |
2443 library.metadata.forEach(onMetadata); | 2354 library.metadata.forEach(onMetadata); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2572 | 2483 |
2573 FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters; | 2484 FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters; |
2574 | 2485 |
2575 void forgetElement(Element element) { | 2486 void forgetElement(Element element) { |
2576 constants.forgetElement(element); | 2487 constants.forgetElement(element); |
2577 constantCompilerTask.dartConstantCompiler.forgetElement(element); | 2488 constantCompilerTask.dartConstantCompiler.forgetElement(element); |
2578 aliasedSuperMembers.remove(element); | 2489 aliasedSuperMembers.remove(element); |
2579 } | 2490 } |
2580 | 2491 |
2581 @override | 2492 @override |
2582 WorldImpact computeMainImpact(Enqueuer enqueuer, MethodElement mainMethod) { | 2493 WorldImpact computeMainImpact(MethodElement mainMethod, |
| 2494 {bool forResolution}) { |
2583 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | 2495 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
2584 if (mainMethod.parameters.isNotEmpty) { | 2496 if (mainMethod.parameters.isNotEmpty) { |
2585 impactTransformer.registerBackendImpact( | 2497 impactTransformer.registerBackendImpact( |
2586 mainImpact, impacts.mainWithArguments); | 2498 mainImpact, impacts.mainWithArguments); |
2587 mainImpact.registerStaticUse( | 2499 mainImpact.registerStaticUse( |
2588 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); | 2500 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); |
2589 // If the main method takes arguments, this compilation could be the | 2501 // If the main method takes arguments, this compilation could be the |
2590 // target of Isolate.spawnUri. Strictly speaking, that can happen also if | 2502 // target of Isolate.spawnUri. Strictly speaking, that can happen also if |
2591 // main takes no arguments, but in this case the spawned isolate can't | 2503 // main takes no arguments, but in this case the spawned isolate can't |
2592 // communicate with the spawning isolate. | 2504 // communicate with the spawning isolate. |
2593 enqueuer.enableIsolateSupport(); | 2505 mainImpact.addImpact(enableIsolateSupport(forResolution: forResolution)); |
2594 } | 2506 } |
2595 mainImpact.registerStaticUse( | 2507 mainImpact.registerStaticUse( |
2596 new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS)); | 2508 new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS)); |
2597 return mainImpact; | 2509 return mainImpact; |
2598 } | 2510 } |
2599 | 2511 |
2600 /// Returns the filename for the output-unit named [name]. | 2512 /// Returns the filename for the output-unit named [name]. |
2601 /// | 2513 /// |
2602 /// The filename is of the form "<main output file>_<name>.part.js". | 2514 /// The filename is of the form "<main output file>_<name>.part.js". |
2603 /// If [addExtension] is false, the ".part.js" suffix is left out. | 2515 /// If [addExtension] is false, the ".part.js" suffix is left out. |
2604 String deferredPartFileName(String name, {bool addExtension: true}) { | 2516 String deferredPartFileName(String name, {bool addExtension: true}) { |
2605 assert(name != ""); | 2517 assert(name != ""); |
2606 String outPath = compiler.options.outputUri != null | 2518 String outPath = compiler.options.outputUri != null |
2607 ? compiler.options.outputUri.path | 2519 ? compiler.options.outputUri.path |
2608 : "out"; | 2520 : "out"; |
2609 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); | 2521 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); |
2610 String extension = addExtension ? ".part.js" : ""; | 2522 String extension = addExtension ? ".part.js" : ""; |
2611 return "${outName}_$name$extension"; | 2523 return "${outName}_$name$extension"; |
2612 } | 2524 } |
2613 | 2525 |
2614 @override | 2526 @override |
2615 bool enableDeferredLoadingIfSupported( | 2527 bool enableDeferredLoadingIfSupported(Spannable node) => true; |
2616 ResolutionEnqueuer enqueuer, Spannable node) { | |
2617 registerCheckDeferredIsLoaded(enqueuer); | |
2618 return true; | |
2619 } | |
2620 | 2528 |
2621 @override | 2529 @override |
2622 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; | 2530 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; |
2623 | 2531 |
2624 jsAst.Expression rewriteAsync( | 2532 jsAst.Expression rewriteAsync( |
2625 FunctionElement element, jsAst.Expression code) { | 2533 FunctionElement element, jsAst.Expression code) { |
2626 AsyncRewriterBase rewriter = null; | 2534 AsyncRewriterBase rewriter = null; |
2627 jsAst.Name name = namer.methodPropertyName(element); | 2535 jsAst.Name name = namer.methodPropertyName(element); |
2628 switch (element.asyncMarker) { | 2536 switch (element.asyncMarker) { |
2629 case AsyncMarker.ASYNC: | 2537 case AsyncMarker.ASYNC: |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 } | 2912 } |
3005 | 2913 |
3006 for (native.NativeBehavior behavior in worldImpact.nativeData) { | 2914 for (native.NativeBehavior behavior in worldImpact.nativeData) { |
3007 enqueuer.nativeEnqueuer | 2915 enqueuer.nativeEnqueuer |
3008 .registerNativeBehavior(transformed, behavior, worldImpact); | 2916 .registerNativeBehavior(transformed, behavior, worldImpact); |
3009 } | 2917 } |
3010 | 2918 |
3011 return transformed; | 2919 return transformed; |
3012 } | 2920 } |
3013 | 2921 |
| 2922 WorldImpact createImpactFor(BackendImpact impact) { |
| 2923 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 2924 registerBackendImpact(impactBuilder, impact); |
| 2925 return impactBuilder; |
| 2926 } |
| 2927 |
| 2928 void registerBackendStaticUse( |
| 2929 WorldImpactBuilder worldImpact, MethodElement element, |
| 2930 {bool isGlobal: false}) { |
| 2931 backend.registerBackendUse(element); |
| 2932 worldImpact.registerStaticUse( |
| 2933 // TODO(johnniwinther): Store the correct use in impacts. |
| 2934 new StaticUse.foreignUse(element)); |
| 2935 if (isGlobal) { |
| 2936 backend.compiler.globalDependencies.registerDependency(element); |
| 2937 } |
| 2938 } |
| 2939 |
| 2940 void registerBackendInstantiation( |
| 2941 WorldImpactBuilder worldImpact, ClassElement cls, |
| 2942 {bool isGlobal: false}) { |
| 2943 cls.ensureResolved(backend.resolution); |
| 2944 backend.registerBackendUse(cls); |
| 2945 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); |
| 2946 if (isGlobal) { |
| 2947 backend.compiler.globalDependencies.registerDependency(cls); |
| 2948 } |
| 2949 } |
| 2950 |
3014 void registerBackendImpact( | 2951 void registerBackendImpact( |
3015 WorldImpactBuilder worldImpact, BackendImpact backendImpact) { | 2952 WorldImpactBuilder worldImpact, BackendImpact backendImpact) { |
3016 for (Element staticUse in backendImpact.staticUses) { | 2953 for (Element staticUse in backendImpact.staticUses) { |
3017 assert(staticUse != null); | 2954 assert(staticUse != null); |
3018 backend.registerBackendUse(staticUse); | 2955 registerBackendStaticUse(worldImpact, staticUse); |
3019 worldImpact.registerStaticUse( | 2956 } |
3020 // TODO(johnniwinther): Store the correct use in impacts. | 2957 for (Element staticUse in backendImpact.globalUses) { |
3021 new StaticUse.foreignUse(staticUse)); | 2958 assert(staticUse != null); |
| 2959 registerBackendStaticUse(worldImpact, staticUse, isGlobal: true); |
3022 } | 2960 } |
3023 for (Selector selector in backendImpact.dynamicUses) { | 2961 for (Selector selector in backendImpact.dynamicUses) { |
3024 assert(selector != null); | 2962 assert(selector != null); |
3025 worldImpact.registerDynamicUse(new DynamicUse(selector, null)); | 2963 worldImpact.registerDynamicUse(new DynamicUse(selector, null)); |
3026 } | 2964 } |
3027 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) { | 2965 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) { |
3028 backend.registerBackendUse(instantiatedType.element); | 2966 backend.registerBackendUse(instantiatedType.element); |
3029 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); | 2967 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
3030 } | 2968 } |
3031 for (ClassElement cls in backendImpact.instantiatedClasses) { | 2969 for (ClassElement cls in backendImpact.instantiatedClasses) { |
3032 cls.ensureResolved(backend.resolution); | 2970 registerBackendInstantiation(worldImpact, cls); |
3033 backend.registerBackendUse(cls); | 2971 } |
3034 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); | 2972 for (ClassElement cls in backendImpact.globalClasses) { |
| 2973 registerBackendInstantiation(worldImpact, cls, isGlobal: true); |
3035 } | 2974 } |
3036 for (BackendImpact otherImpact in backendImpact.otherImpacts) { | 2975 for (BackendImpact otherImpact in backendImpact.otherImpacts) { |
3037 registerBackendImpact(worldImpact, otherImpact); | 2976 registerBackendImpact(worldImpact, otherImpact); |
3038 } | 2977 } |
3039 for (BackendFeature feature in backendImpact.features) { | 2978 for (BackendFeature feature in backendImpact.features) { |
3040 switch (feature) { | 2979 switch (feature) { |
3041 case BackendFeature.needToInitializeDispatchProperty: | 2980 case BackendFeature.needToInitializeDispatchProperty: |
3042 backend.needToInitializeDispatchProperty = true; | 2981 backend.needToInitializeDispatchProperty = true; |
3043 break; | 2982 break; |
3044 case BackendFeature.needToInitializeIsolateAffinityTag: | 2983 case BackendFeature.needToInitializeIsolateAffinityTag: |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3290 ClassElement get mapImplementation => helpers.mapLiteralClass; | 3229 ClassElement get mapImplementation => helpers.mapLiteralClass; |
3291 ClassElement get constMapImplementation => helpers.constMapLiteralClass; | 3230 ClassElement get constMapImplementation => helpers.constMapLiteralClass; |
3292 ClassElement get typeImplementation => helpers.typeLiteralClass; | 3231 ClassElement get typeImplementation => helpers.typeLiteralClass; |
3293 ClassElement get boolImplementation => helpers.jsBoolClass; | 3232 ClassElement get boolImplementation => helpers.jsBoolClass; |
3294 ClassElement get nullImplementation => helpers.jsNullClass; | 3233 ClassElement get nullImplementation => helpers.jsNullClass; |
3295 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; | 3234 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; |
3296 ClassElement get asyncFutureImplementation => helpers.futureImplementation; | 3235 ClassElement get asyncFutureImplementation => helpers.futureImplementation; |
3297 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; | 3236 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; |
3298 ClassElement get functionImplementation => helpers.coreClasses.functionClass; | 3237 ClassElement get functionImplementation => helpers.coreClasses.functionClass; |
3299 } | 3238 } |
OLD | NEW |