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 |