| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Generates the code for all used classes in the program. Static fields (even | 8 * Generates the code for all used classes in the program. Static fields (even |
| 9 * in classes) are ignored, since they can be treated as non-class elements. | 9 * in classes) are ignored, since they can be treated as non-class elements. |
| 10 * | 10 * |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = | 48 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = |
| 49 new Map<ClassElement, Map<String, jsAst.Expression>>(); | 49 new Map<ClassElement, Map<String, jsAst.Expression>>(); |
| 50 | 50 |
| 51 /// Records if a type variable is read dynamically for type tests. | 51 /// Records if a type variable is read dynamically for type tests. |
| 52 final Set<TypeVariableElement> readTypeVariables = | 52 final Set<TypeVariableElement> readTypeVariables = |
| 53 new Set<TypeVariableElement>(); | 53 new Set<TypeVariableElement>(); |
| 54 | 54 |
| 55 // TODO(ngeoffray): remove this field. | 55 // TODO(ngeoffray): remove this field. |
| 56 Set<ClassElement> instantiatedClasses; | 56 Set<ClassElement> instantiatedClasses; |
| 57 | 57 |
| 58 List<TypedefElement> typedefsNeededForReflection; |
| 59 |
| 58 JavaScriptBackend get backend => compiler.backend; | 60 JavaScriptBackend get backend => compiler.backend; |
| 59 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler; | 61 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler; |
| 60 | 62 |
| 61 String get _ => space; | 63 String get _ => space; |
| 62 String get space => compiler.enableMinification ? "" : " "; | 64 String get space => compiler.enableMinification ? "" : " "; |
| 63 String get n => compiler.enableMinification ? "" : "\n"; | 65 String get n => compiler.enableMinification ? "" : "\n"; |
| 64 String get N => compiler.enableMinification ? "\n" : ";\n"; | 66 String get N => compiler.enableMinification ? "\n" : ";\n"; |
| 65 | 67 |
| 68 CodeBuffer getBuffer(OutputUnit outputUnit) { |
| 69 return outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer()); |
| 70 } |
| 71 |
| 66 CodeBuffer get mainBuffer { | 72 CodeBuffer get mainBuffer { |
| 67 return outputBuffers.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, | 73 return getBuffer(compiler.deferredLoadTask.mainOutputUnit); |
| 68 () => new CodeBuffer()); | |
| 69 } | 74 } |
| 70 | 75 |
| 71 /** | 76 /** |
| 72 * List of expressions and statements that will be included in the | 77 * List of expressions and statements that will be included in the |
| 73 * precompiled function. | 78 * precompiled function. |
| 74 * | 79 * |
| 75 * To save space, dart2js normally generates constructors and accessors | 80 * To save space, dart2js normally generates constructors and accessors |
| 76 * dynamically. This doesn't work in CSP mode, and may impact startup time | 81 * dynamically. This doesn't work in CSP mode, and may impact startup time |
| 77 * negatively. So dart2js will emit these functions to a separate file that | 82 * negatively. So dart2js will emit these functions to a separate file that |
| 78 * can be optionally included to support CSP mode or for faster startup. | 83 * can be optionally included to support CSP mode or for faster startup. |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 '$namedArguments'; | 750 '$namedArguments'; |
| 746 return (isConstructor) ? 'new $suffix' : suffix; | 751 return (isConstructor) ? 'new $suffix' : suffix; |
| 747 } | 752 } |
| 748 Element element = elementOrSelector; | 753 Element element = elementOrSelector; |
| 749 if (element.isGenerativeConstructorBody) { | 754 if (element.isGenerativeConstructorBody) { |
| 750 return null; | 755 return null; |
| 751 } else if (element.isClass) { | 756 } else if (element.isClass) { |
| 752 ClassElement cls = element; | 757 ClassElement cls = element; |
| 753 if (cls.isUnnamedMixinApplication) return null; | 758 if (cls.isUnnamedMixinApplication) return null; |
| 754 return cls.name; | 759 return cls.name; |
| 760 } else if (element.isTypedef) { |
| 761 return element.name; |
| 755 } | 762 } |
| 756 throw compiler.internalError(element, | 763 throw compiler.internalError(element, |
| 757 'Do not know how to reflect on this $element.'); | 764 'Do not know how to reflect on this $element.'); |
| 758 } | 765 } |
| 759 | 766 |
| 760 String namedParametersAsReflectionNames(Selector selector) { | 767 String namedParametersAsReflectionNames(Selector selector) { |
| 761 if (selector.getOrderedNamedArguments().isEmpty) return ''; | 768 if (selector.getOrderedNamedArguments().isEmpty) return ''; |
| 762 String names = selector.getOrderedNamedArguments().join(':'); | 769 String names = selector.getOrderedNamedArguments().join(':'); |
| 763 return ':$names'; | 770 return ':$names'; |
| 764 } | 771 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 void emitStaticFunctions() { | 861 void emitStaticFunctions() { |
| 855 bool isStaticFunction(Element element) => | 862 bool isStaticFunction(Element element) => |
| 856 !element.isInstanceMember && !element.isField; | 863 !element.isInstanceMember && !element.isField; |
| 857 | 864 |
| 858 Iterable<Element> elements = | 865 Iterable<Element> elements = |
| 859 backend.generatedCode.keys.where(isStaticFunction); | 866 backend.generatedCode.keys.where(isStaticFunction); |
| 860 | 867 |
| 861 for (Element element in Elements.sortedByPosition(elements)) { | 868 for (Element element in Elements.sortedByPosition(elements)) { |
| 862 ClassBuilder builder = new ClassBuilder(element, namer); | 869 ClassBuilder builder = new ClassBuilder(element, namer); |
| 863 containerBuilder.addMember(element, builder); | 870 containerBuilder.addMember(element, builder); |
| 864 getElementDecriptor(element).properties.addAll(builder.properties); | 871 getElementDescriptor(element).properties.addAll(builder.properties); |
| 865 } | 872 } |
| 866 } | 873 } |
| 867 | 874 |
| 868 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 875 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
| 869 JavaScriptConstantCompiler handler = backend.constants; | 876 JavaScriptConstantCompiler handler = backend.constants; |
| 870 Iterable<VariableElement> staticNonFinalFields = | 877 Iterable<VariableElement> staticNonFinalFields = |
| 871 handler.getStaticNonFinalFieldsForEmission(); | 878 handler.getStaticNonFinalFieldsForEmission(); |
| 872 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 879 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { |
| 873 // [:interceptedNames:] is handled in [emitInterceptedNames]. | 880 // [:interceptedNames:] is handled in [emitInterceptedNames]. |
| 874 if (element == backend.interceptedNames) continue; | 881 if (element == backend.interceptedNames) continue; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 // The back-end introduces some constants, like "InterceptorConstant" or | 1149 // The back-end introduces some constants, like "InterceptorConstant" or |
| 1143 // some list constants. They are emitted in the main output-unit. | 1150 // some list constants. They are emitted in the main output-unit. |
| 1144 // TODO(sigurdm): We should track those constants. | 1151 // TODO(sigurdm): We should track those constants. |
| 1145 constantUnit = compiler.deferredLoadTask.mainOutputUnit; | 1152 constantUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1146 } | 1153 } |
| 1147 outputConstantLists.putIfAbsent(constantUnit, () => new List<Constant>()) | 1154 outputConstantLists.putIfAbsent(constantUnit, () => new List<Constant>()) |
| 1148 .add(constant); | 1155 .add(constant); |
| 1149 } | 1156 } |
| 1150 } | 1157 } |
| 1151 | 1158 |
| 1152 /** | 1159 /// Compute all the classes and typedefs that must be emitted. |
| 1153 * Compute all the classes that must be emitted. | 1160 void computeNeededDeclarations() { |
| 1154 */ | 1161 // Compute needed typedefs. |
| 1155 void computeNeededClasses() { | 1162 typedefsNeededForReflection = Elements.sortedByPosition( |
| 1163 compiler.world.allTypedefs |
| 1164 .where(backend.isAccessibleByReflection) |
| 1165 .toList()); |
| 1166 |
| 1167 // Compute needed classes. |
| 1156 instantiatedClasses = | 1168 instantiatedClasses = |
| 1157 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) | 1169 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) |
| 1158 .toSet(); | 1170 .toSet(); |
| 1159 | 1171 |
| 1160 void addClassWithSuperclasses(ClassElement cls) { | 1172 void addClassWithSuperclasses(ClassElement cls) { |
| 1161 neededClasses.add(cls); | 1173 neededClasses.add(cls); |
| 1162 for (ClassElement superclass = cls.superclass; | 1174 for (ClassElement superclass = cls.superclass; |
| 1163 superclass != null; | 1175 superclass != null; |
| 1164 superclass = superclass.superclass) { | 1176 superclass = superclass.superclass) { |
| 1165 neededClasses.add(superclass); | 1177 neededClasses.add(superclass); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 } | 1316 } |
| 1305 | 1317 |
| 1306 void writeLibraryDescriptors(LibraryElement library) { | 1318 void writeLibraryDescriptors(LibraryElement library) { |
| 1307 var uri = ""; | 1319 var uri = ""; |
| 1308 if (!compiler.enableMinification || backend.mustRetainUris) { | 1320 if (!compiler.enableMinification || backend.mustRetainUris) { |
| 1309 uri = library.canonicalUri; | 1321 uri = library.canonicalUri; |
| 1310 if (uri.scheme == 'file' && compiler.outputUri != null) { | 1322 if (uri.scheme == 'file' && compiler.outputUri != null) { |
| 1311 uri = relativize(compiler.outputUri, library.canonicalUri, false); | 1323 uri = relativize(compiler.outputUri, library.canonicalUri, false); |
| 1312 } | 1324 } |
| 1313 } | 1325 } |
| 1326 Map<OutputUnit, ClassBuilder> descriptors = elementDescriptors[library]; |
| 1314 String libraryName = | 1327 String libraryName = |
| 1315 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? | 1328 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? |
| 1316 library.getLibraryName() : | 1329 library.getLibraryName() : |
| 1317 ""; | 1330 ""; |
| 1318 Map<OutputUnit, ClassBuilder> descriptors = | |
| 1319 elementDescriptors[library]; | |
| 1320 | 1331 |
| 1321 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { | 1332 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { |
| 1322 ClassBuilder descriptor = | 1333 if (!descriptors.containsKey(outputUnit)) continue; |
| 1323 descriptors.putIfAbsent(outputUnit, | 1334 |
| 1324 () => new ClassBuilder(library, namer)); | 1335 ClassBuilder descriptor = descriptors[outputUnit]; |
| 1325 if (descriptor.properties.isEmpty) continue; | |
| 1326 bool isDeferred = | |
| 1327 outputUnit != compiler.deferredLoadTask.mainOutputUnit; | |
| 1328 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); | 1336 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); |
| 1329 | 1337 |
| 1330 jsAst.ObjectInitializer initializers = | 1338 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer(); |
| 1331 descriptor.toObjectInitializer(); | 1339 CodeBuffer outputBuffer = getBuffer(outputUnit); |
| 1332 CodeBuffer outputBuffer = | 1340 |
| 1333 outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer()); | |
| 1334 int sizeBefore = outputBuffer.length; | 1341 int sizeBefore = outputBuffer.length; |
| 1335 compiler.dumpInfoTask.registerElementAst(library, metadata); | 1342 compiler.dumpInfoTask.registerElementAst(library, metadata); |
| 1336 compiler.dumpInfoTask.registerElementAst(library, initializers); | 1343 compiler.dumpInfoTask.registerElementAst(library, initializers); |
| 1337 outputBuffers[outputUnit] | 1344 outputBuffers[outputUnit] |
| 1338 ..write('["$libraryName",$_') | 1345 ..write('["$libraryName",$_') |
| 1339 ..write('"${uri}",$_') | 1346 ..write('"${uri}",$_') |
| 1340 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata, | 1347 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata, |
| 1341 compiler, | 1348 compiler, |
| 1342 monitor: compiler.dumpInfoTask)) | 1349 monitor: compiler.dumpInfoTask)) |
| 1343 ..write(',$_') | 1350 ..write(',$_') |
| 1344 ..write(namer.globalObjectFor(library)) | 1351 ..write(namer.globalObjectFor(library)) |
| 1345 ..write(',$_') | 1352 ..write(',$_') |
| 1346 ..write(jsAst.prettyPrint(initializers, | 1353 ..write(jsAst.prettyPrint(initializers, |
| 1347 compiler, | 1354 compiler, |
| 1348 monitor: compiler.dumpInfoTask)) | 1355 monitor: compiler.dumpInfoTask)) |
| 1349 ..write(library == compiler.mainApp ? ',${n}1' : "") | 1356 ..write(library == compiler.mainApp ? ',${n}1' : "") |
| 1350 ..write('],$n'); | 1357 ..write('],$n'); |
| 1351 int sizeAfter = outputBuffer.length; | 1358 int sizeAfter = outputBuffer.length; |
| 1352 } | 1359 } |
| 1353 } | 1360 } |
| 1354 | 1361 |
| 1362 void emitPrecompiledConstructor(String constructorName, |
| 1363 jsAst.Expression constructorAst) { |
| 1364 precompiledFunction.add( |
| 1365 new jsAst.FunctionDeclaration( |
| 1366 new jsAst.VariableDeclaration(constructorName), constructorAst)); |
| 1367 precompiledFunction.add( |
| 1368 js.statement(r'''{ |
| 1369 #.builtin$cls = #; |
| 1370 if (!"name" in #) |
| 1371 #.name = #; |
| 1372 $desc=$collectedClasses.#; |
| 1373 if ($desc instanceof Array) $desc = $desc[1]; |
| 1374 #.prototype = $desc; |
| 1375 }''', |
| 1376 [ constructorName, js.string(constructorName), |
| 1377 constructorName, |
| 1378 constructorName, js.string(constructorName), |
| 1379 constructorName, |
| 1380 constructorName |
| 1381 ])); |
| 1382 |
| 1383 precompiledConstructorNames.add(js('#', constructorName)); |
| 1384 } |
| 1385 |
| 1355 String assembleProgram() { | 1386 String assembleProgram() { |
| 1356 measure(() { | 1387 measure(() { |
| 1357 invalidateCaches(); | 1388 invalidateCaches(); |
| 1358 | 1389 |
| 1359 // Compute the required type checks to know which classes need a | 1390 // Compute the required type checks to know which classes need a |
| 1360 // 'is$' method. | 1391 // 'is$' method. |
| 1361 typeTestEmitter.computeRequiredTypeChecks(); | 1392 typeTestEmitter.computeRequiredTypeChecks(); |
| 1362 | 1393 |
| 1363 computeNeededClasses(); | 1394 computeNeededDeclarations(); |
| 1364 | 1395 |
| 1365 mainBuffer.add(buildGeneratedBy()); | 1396 mainBuffer.add(buildGeneratedBy()); |
| 1366 addComment(HOOKS_API_USAGE, mainBuffer); | 1397 addComment(HOOKS_API_USAGE, mainBuffer); |
| 1367 | 1398 |
| 1368 if (!compiler.deferredLoadTask.splitProgram) { | 1399 if (!compiler.deferredLoadTask.splitProgram) { |
| 1369 mainBuffer.add('(function(${namer.currentIsolate})$_{$n'); | 1400 mainBuffer.add('(function(${namer.currentIsolate})$_{$n'); |
| 1370 } | 1401 } |
| 1371 | 1402 |
| 1372 // Using a named function here produces easier to read stack traces in | 1403 // Using a named function here produces easier to read stack traces in |
| 1373 // Chrome/V8. | 1404 // Chrome/V8. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1388 // Shorten the code by using [namer.currentIsolate] as temporary. | 1419 // Shorten the code by using [namer.currentIsolate] as temporary. |
| 1389 isolateProperties = namer.currentIsolate; | 1420 isolateProperties = namer.currentIsolate; |
| 1390 mainBuffer.add( | 1421 mainBuffer.add( |
| 1391 '$isolateProperties$_=$_$isolatePropertiesName$N'); | 1422 '$isolateProperties$_=$_$isolatePropertiesName$N'); |
| 1392 | 1423 |
| 1393 emitStaticFunctions(); | 1424 emitStaticFunctions(); |
| 1394 | 1425 |
| 1395 // Only output the classesCollector if we actually have any classes. | 1426 // Only output the classesCollector if we actually have any classes. |
| 1396 if (!(nativeClasses.isEmpty && | 1427 if (!(nativeClasses.isEmpty && |
| 1397 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && | 1428 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && |
| 1398 outputClassLists.values.every((classList) => classList.isEmpty))) { | 1429 outputClassLists.values.every((classList) => classList.isEmpty) && |
| 1430 typedefsNeededForReflection.isEmpty)) { |
| 1399 // Shorten the code by using "$$" as temporary. | 1431 // Shorten the code by using "$$" as temporary. |
| 1400 classesCollector = r"$$"; | 1432 classesCollector = r"$$"; |
| 1401 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); | 1433 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); |
| 1402 } | 1434 } |
| 1403 | 1435 |
| 1404 // Emit native classes on [nativeBuffer]. | 1436 // Emit native classes on [nativeBuffer]. |
| 1405 // Might create methodClosures. | 1437 // Might create methodClosures. |
| 1406 final CodeBuffer nativeBuffer = new CodeBuffer(); | 1438 final CodeBuffer nativeBuffer = new CodeBuffer(); |
| 1407 if (!nativeClasses.isEmpty) { | 1439 if (!nativeClasses.isEmpty) { |
| 1408 addComment('Native classes', nativeBuffer); | 1440 addComment('Native classes', nativeBuffer); |
| 1409 addComment('Native classes', mainBuffer); | 1441 addComment('Native classes', mainBuffer); |
| 1410 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer, | 1442 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer, |
| 1411 additionalProperties); | 1443 additionalProperties); |
| 1412 } | 1444 } |
| 1413 | 1445 |
| 1414 // As a side-effect, emitting classes will produce "bound closures" in | 1446 // As a side-effect, emitting classes will produce "bound closures" in |
| 1415 // [methodClosures]. The bound closures are JS AST nodes that add | 1447 // [methodClosures]. The bound closures are JS AST nodes that add |
| 1416 // properties to $$ [classesCollector]. The bound closures are not | 1448 // properties to $$ [classesCollector]. The bound closures are not |
| 1417 // emitted until we have emitted all other classes (native or not). | 1449 // emitted until we have emitted all other classes (native or not). |
| 1418 | 1450 |
| 1419 // Might create methodClosures. | 1451 // Might create methodClosures. |
| 1420 for (List<ClassElement> outputClassList in outputClassLists.values) { | 1452 for (List<ClassElement> outputClassList in outputClassLists.values) { |
| 1421 for (ClassElement element in outputClassList) { | 1453 for (ClassElement element in outputClassList) { |
| 1422 generateClass(element, getElementDecriptor(element)); | 1454 generateClass(element, getElementDescriptor(element)); |
| 1423 } | 1455 } |
| 1424 } | 1456 } |
| 1425 | 1457 |
| 1426 nativeEmitter.finishGenerateNativeClasses(); | 1458 nativeEmitter.finishGenerateNativeClasses(); |
| 1427 nativeEmitter.assembleCode(nativeBuffer); | 1459 nativeEmitter.assembleCode(nativeBuffer); |
| 1428 | 1460 |
| 1429 | 1461 |
| 1430 // After this assignment we will produce invalid JavaScript code if we use | 1462 // After this assignment we will produce invalid JavaScript code if we use |
| 1431 // the classesCollector variable. | 1463 // the classesCollector variable. |
| 1432 classesCollector = 'classesCollector should not be used from now on'; | 1464 classesCollector = 'classesCollector should not be used from now on'; |
| 1433 | 1465 |
| 1434 // TODO(sigurdm): Need to check this for each outputUnit. | 1466 // TODO(sigurdm): Need to check this for each outputUnit. |
| 1435 if (!elementDescriptors.isEmpty) { | 1467 if (!elementDescriptors.isEmpty) { |
| 1436 var oldClassesCollector = classesCollector; | 1468 var oldClassesCollector = classesCollector; |
| 1437 classesCollector = r"$$"; | 1469 classesCollector = r"$$"; |
| 1438 if (compiler.enableMinification) { | 1470 if (compiler.enableMinification) { |
| 1439 mainBuffer.write(';'); | 1471 mainBuffer.write(';'); |
| 1440 } | 1472 } |
| 1441 | 1473 |
| 1474 // TODO(karlklose): document what kinds of fields this loop adds to the |
| 1475 // library class builder. |
| 1442 for (Element element in elementDescriptors.keys) { | 1476 for (Element element in elementDescriptors.keys) { |
| 1443 // TODO(ahe): Should iterate over all libraries. Otherwise, we will | 1477 // TODO(ahe): Should iterate over all libraries. Otherwise, we will |
| 1444 // not see libraries that only have fields. | 1478 // not see libraries that only have fields. |
| 1445 if (element.isLibrary) { | 1479 if (element.isLibrary) { |
| 1446 LibraryElement library = element; | 1480 LibraryElement library = element; |
| 1447 ClassBuilder builder = new ClassBuilder(library, namer); | 1481 ClassBuilder builder = new ClassBuilder(library, namer); |
| 1448 if (classEmitter.emitFields( | 1482 if (classEmitter.emitFields( |
| 1449 library, builder, null, emitStatics: true)) { | 1483 library, builder, null, emitStatics: true)) { |
| 1450 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; | 1484 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1451 jsAst.ObjectInitializer initializer = | 1485 jsAst.ObjectInitializer initializer = |
| 1452 builder.toObjectInitializer(); | 1486 builder.toObjectInitializer(); |
| 1453 compiler.dumpInfoTask.registerElementAst(builder.element, | 1487 compiler.dumpInfoTask.registerElementAst(builder.element, |
| 1454 initializer); | 1488 initializer); |
| 1455 getElementDescriptorForOutputUnit(library, mainUnit) | 1489 getElementDescriptorForOutputUnit(library, mainUnit) |
| 1456 .properties.addAll(initializer.properties); | 1490 .properties.addAll(initializer.properties); |
| 1457 } | 1491 } |
| 1458 } | 1492 } |
| 1459 } | 1493 } |
| 1460 | 1494 |
| 1495 // Emit all required typedef declarations into the main output unit. |
| 1496 // TODO(karlklose): unify required classes and typedefs to declarations |
| 1497 // and have builders for each kind. |
| 1498 for (TypedefElement typedef in typedefsNeededForReflection) { |
| 1499 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1500 LibraryElement library = typedef.library; |
| 1501 // TODO(karlklose): add a TypedefBuilder and move this code there. |
| 1502 DartType type = typedef.alias; |
| 1503 int typeIndex = metadataEmitter.reifyType(type); |
| 1504 String typeReference = |
| 1505 encoding.encodeTypedefFieldDescriptor(typeIndex); |
| 1506 jsAst.Property descriptor = new jsAst.Property( |
| 1507 js.string(namer.classDescriptorProperty), |
| 1508 js.string(typeReference)); |
| 1509 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]); |
| 1510 String mangledName = namer.getNameX(typedef); |
| 1511 String reflectionName = getReflectionName(typedef, mangledName); |
| 1512 getElementDescriptorForOutputUnit(library, mainUnit) |
| 1513 ..addProperty(mangledName, declaration) |
| 1514 ..addProperty("+$reflectionName", js.string('')); |
| 1515 // Also emit a trivial constructor for CSP mode. |
| 1516 String constructorName = mangledName; |
| 1517 jsAst.Expression constructorAst = js('function() {}'); |
| 1518 emitPrecompiledConstructor(constructorName, constructorAst); |
| 1519 } |
| 1520 |
| 1461 if (!mangledFieldNames.isEmpty) { | 1521 if (!mangledFieldNames.isEmpty) { |
| 1462 var keys = mangledFieldNames.keys.toList(); | 1522 var keys = mangledFieldNames.keys.toList(); |
| 1463 keys.sort(); | 1523 keys.sort(); |
| 1464 var properties = []; | 1524 var properties = []; |
| 1465 for (String key in keys) { | 1525 for (String key in keys) { |
| 1466 var value = js.string('${mangledFieldNames[key]}'); | 1526 var value = js.string('${mangledFieldNames[key]}'); |
| 1467 properties.add(new jsAst.Property(js.string(key), value)); | 1527 properties.add(new jsAst.Property(js.string(key), value)); |
| 1468 } | 1528 } |
| 1469 var map = new jsAst.ObjectInitializer(properties); | 1529 var map = new jsAst.ObjectInitializer(properties); |
| 1470 mainBuffer.write( | 1530 mainBuffer.write( |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1707 | 1767 |
| 1708 ClassBuilder getElementDescriptorForOutputUnit(Element element, | 1768 ClassBuilder getElementDescriptorForOutputUnit(Element element, |
| 1709 OutputUnit outputUnit) { | 1769 OutputUnit outputUnit) { |
| 1710 Map<OutputUnit, ClassBuilder> descriptors = | 1770 Map<OutputUnit, ClassBuilder> descriptors = |
| 1711 elementDescriptors.putIfAbsent( | 1771 elementDescriptors.putIfAbsent( |
| 1712 element, () => new Map<OutputUnit, ClassBuilder>()); | 1772 element, () => new Map<OutputUnit, ClassBuilder>()); |
| 1713 return descriptors.putIfAbsent(outputUnit, | 1773 return descriptors.putIfAbsent(outputUnit, |
| 1714 () => new ClassBuilder(element, namer)); | 1774 () => new ClassBuilder(element, namer)); |
| 1715 } | 1775 } |
| 1716 | 1776 |
| 1717 ClassBuilder getElementDecriptor(Element element) { | 1777 ClassBuilder getElementDescriptor(Element element) { |
| 1718 Element owner = element.library; | 1778 Element owner = element.library; |
| 1719 if (!element.isTopLevel && !element.isNative) { | 1779 if (!element.isTopLevel && !element.isNative) { |
| 1720 // For static (not top level) elements, record their code in a buffer | 1780 // For static (not top level) elements, record their code in a buffer |
| 1721 // specific to the class. For now, not supported for native classes and | 1781 // specific to the class. For now, not supported for native classes and |
| 1722 // native elements. | 1782 // native elements. |
| 1723 ClassElement cls = | 1783 ClassElement cls = |
| 1724 element.enclosingClassOrCompilationUnit.declaration; | 1784 element.enclosingClassOrCompilationUnit.declaration; |
| 1725 if (compiler.codegenWorld.instantiatedClasses.contains(cls) | 1785 if (compiler.codegenWorld.instantiatedClasses.contains(cls) |
| 1726 && !cls.isNative) { | 1786 && !cls.isNative) { |
| 1727 owner = cls; | 1787 owner = cls; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1822 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1882 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 1823 if (element.isInstanceMember) { | 1883 if (element.isInstanceMember) { |
| 1824 cachedClassBuilders.remove(element.enclosingClass); | 1884 cachedClassBuilders.remove(element.enclosingClass); |
| 1825 | 1885 |
| 1826 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1886 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 1827 | 1887 |
| 1828 } | 1888 } |
| 1829 } | 1889 } |
| 1830 } | 1890 } |
| 1831 } | 1891 } |
| OLD | NEW |