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 js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
9 * from the given element. | 9 * from the given element. |
10 */ | 10 */ |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 /* The 'fields' are either a constructor function or a | 605 /* The 'fields' are either a constructor function or a |
606 * string encoding fields, constructor and superclass. Get | 606 * string encoding fields, constructor and superclass. Get |
607 * the superclass and the fields in the format | 607 * the superclass and the fields in the format |
608 * '[name/]Super;field1,field2' | 608 * '[name/]Super;field1,field2' |
609 * from the null-string property on the descriptor. | 609 * from the null-string property on the descriptor. |
610 * The 'name/' is optional and contains the name that should be used | 610 * The 'name/' is optional and contains the name that should be used |
611 * when printing the runtime type string. It is used, for example, to | 611 * when printing the runtime type string. It is used, for example, to |
612 * print the runtime type JSInt as 'int'. | 612 * print the runtime type JSInt as 'int'. |
613 */ | 613 */ |
614 js('var classData = desc[""], supr, name = cls, fields = classData'), | 614 js('var classData = desc[""], supr, name = cls, fields = classData'), |
| 615 optional( |
| 616 compiler.mirrorSystemClass != null, |
| 617 js.if_('typeof classData == "object" && ' |
| 618 'classData instanceof Array', |
| 619 [js('classData = fields = classData[0]')])), |
| 620 |
615 js.if_('typeof classData == "string"', [ | 621 js.if_('typeof classData == "string"', [ |
616 js('var split = classData.split("/")'), | 622 js('var split = classData.split("/")'), |
617 js.if_('split.length == 2', [ | 623 js.if_('split.length == 2', [ |
618 js('name = split[0]'), | 624 js('name = split[0]'), |
619 js('fields = split[1]') | 625 js('fields = split[1]') |
620 ]) | 626 ]) |
621 ]), | 627 ]), |
622 | 628 |
623 js.if_('typeof fields == "string"', [ | 629 js.if_('typeof fields == "string"', [ |
624 js('var s = fields.split(";")'), | 630 js('var s = fields.split(";")'), |
625 js('fields = s[1] == "" ? [] : s[1].split(",")'), | 631 js('fields = s[1] == "" ? [] : s[1].split(",")'), |
626 js('supr = s[0]'), | 632 js('supr = s[0]'), |
627 ], /* else */ [ | 633 ], /* else */ [ |
628 js('supr = desc.super'), | 634 js('supr = desc.super'), |
629 js.if_(r'!!desc.$name', js(r'name = desc.$name')) | 635 js.if_(r'!!desc.$name', js(r'name = desc.$name')) |
630 ]), | 636 ]), |
631 | 637 |
632 optional(needsMixinSupport, js.if_('supr && supr.indexOf("+") > 0', [ | 638 optional(needsMixinSupport, js.if_('supr && supr.indexOf("+") > 0', [ |
633 js('s = supr.split("+")'), | 639 js('s = supr.split("+")'), |
634 js('supr = s[0]'), | 640 js('supr = s[0]'), |
635 js('var mixin = collectedClasses[s[1]]'), | 641 js('var mixin = collectedClasses[s[1]]'), |
636 js.forIn('d', 'mixin', [ | 642 js.forIn('d', 'mixin', [ |
637 js.if_('hasOwnProperty.call(mixin, d)' | 643 js.if_('hasOwnProperty.call(mixin, d)' |
638 '&& !hasOwnProperty.call(desc, d)', | 644 '&& !hasOwnProperty.call(desc, d)', |
639 js('desc[d] = mixin[d]')) | 645 js('desc[d] = mixin[d]')) |
640 ]), | 646 ]), |
641 ])), | 647 ])), |
642 | 648 |
643 js('isolateProperties[cls] = defineClass(name, cls, fields, desc)'), | 649 js('var constructor = defineClass(name, cls, fields, desc)'), |
| 650 optional(compiler.mirrorSystemClass != null, |
| 651 js('constructor["${namer.metadataField}"] = desc')), |
| 652 js('isolateProperties[cls] = constructor'), |
644 js.if_('supr', js('pendingClasses[cls] = supr')) | 653 js.if_('supr', js('pendingClasses[cls] = supr')) |
645 ]) | 654 ]) |
646 ]), | 655 ]), |
647 | 656 |
648 js('var finishedClasses = {}'), | 657 js('var finishedClasses = {}'), |
649 | 658 |
650 buildFinishClass(), | 659 buildFinishClass(), |
651 ]; | 660 ]; |
652 | 661 |
653 addTrivialNsmHandlers(statements); | 662 addTrivialNsmHandlers(statements); |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 assert(superName != null); | 1445 assert(superName != null); |
1437 String separator = ''; | 1446 String separator = ''; |
1438 String nativeName = namer.getPrimitiveInterceptorRuntimeName(classElement); | 1447 String nativeName = namer.getPrimitiveInterceptorRuntimeName(classElement); |
1439 StringBuffer buffer = new StringBuffer(); | 1448 StringBuffer buffer = new StringBuffer(); |
1440 if (nativeName != null) { | 1449 if (nativeName != null) { |
1441 buffer.write('$nativeName/'); | 1450 buffer.write('$nativeName/'); |
1442 } | 1451 } |
1443 buffer.write('$superName;'); | 1452 buffer.write('$superName;'); |
1444 int bufferClassLength = buffer.length; | 1453 int bufferClassLength = buffer.length; |
1445 | 1454 |
| 1455 var fieldMetadata = []; |
| 1456 bool hasMetadata = false; |
| 1457 |
1446 visitClassFields(classElement, (Element member, | 1458 visitClassFields(classElement, (Element member, |
1447 String name, | 1459 String name, |
1448 String accessorName, | 1460 String accessorName, |
1449 bool needsGetter, | 1461 bool needsGetter, |
1450 bool needsSetter, | 1462 bool needsSetter, |
1451 bool needsCheckedSetter) { | 1463 bool needsCheckedSetter) { |
1452 // Ignore needsCheckedSetter - that is handled below. | 1464 // Ignore needsCheckedSetter - that is handled below. |
1453 bool needsAccessor = (needsGetter || needsSetter); | 1465 bool needsAccessor = (needsGetter || needsSetter); |
1454 // We need to output the fields for non-native classes so we can auto- | 1466 // We need to output the fields for non-native classes so we can auto- |
1455 // generate the constructor. For native classes there are no | 1467 // generate the constructor. For native classes there are no |
1456 // constructors, so we don't need the fields unless we are generating | 1468 // constructors, so we don't need the fields unless we are generating |
1457 // accessors at runtime. | 1469 // accessors at runtime. |
1458 if (!classIsNative || needsAccessor) { | 1470 if (!classIsNative || needsAccessor) { |
1459 buffer.write(separator); | 1471 buffer.write(separator); |
1460 separator = ','; | 1472 separator = ','; |
| 1473 if (compiler.mirrorSystemClass != null) { |
| 1474 var metadata = buildMetadataFunction(member); |
| 1475 fieldMetadata.add(metadata); |
| 1476 if (metadata != null) { |
| 1477 hasMetadata = true; |
| 1478 } |
| 1479 } |
1461 if (!needsAccessor) { | 1480 if (!needsAccessor) { |
1462 // Emit field for constructor generation. | 1481 // Emit field for constructor generation. |
1463 assert(!classIsNative); | 1482 assert(!classIsNative); |
1464 buffer.write(name); | 1483 buffer.write(name); |
1465 } else { | 1484 } else { |
1466 // Emit (possibly renaming) field name so we can add accessors at | 1485 // Emit (possibly renaming) field name so we can add accessors at |
1467 // runtime. | 1486 // runtime. |
1468 buffer.write(accessorName); | 1487 buffer.write(accessorName); |
1469 if (name != accessorName) { | 1488 if (name != accessorName) { |
1470 buffer.write(':$name'); | 1489 buffer.write(':$name'); |
(...skipping 23 matching lines...) Expand all Loading... |
1494 assert(setterCode != 0); | 1513 assert(setterCode != 0); |
1495 } | 1514 } |
1496 int code = getterCode + (setterCode << 2); | 1515 int code = getterCode + (setterCode << 2); |
1497 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); | 1516 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); |
1498 } | 1517 } |
1499 } | 1518 } |
1500 }); | 1519 }); |
1501 | 1520 |
1502 bool fieldsAdded = buffer.length > bufferClassLength; | 1521 bool fieldsAdded = buffer.length > bufferClassLength; |
1503 String compactClassData = buffer.toString(); | 1522 String compactClassData = buffer.toString(); |
1504 builder.addProperty('', js.string(compactClassData)); | 1523 jsAst.Expression classDataNode = js.string(compactClassData); |
| 1524 if (hasMetadata) { |
| 1525 fieldMetadata.insert(0, classDataNode); |
| 1526 classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata); |
| 1527 } |
| 1528 builder.addProperty('', classDataNode); |
1505 return fieldsAdded; | 1529 return fieldsAdded; |
1506 } | 1530 } |
1507 | 1531 |
1508 void emitClassGettersSetters(ClassElement classElement, | 1532 void emitClassGettersSetters(ClassElement classElement, |
1509 ClassBuilder builder) { | 1533 ClassBuilder builder) { |
1510 | 1534 |
1511 visitClassFields(classElement, (Element member, | 1535 visitClassFields(classElement, (Element member, |
1512 String name, | 1536 String name, |
1513 String accessorName, | 1537 String accessorName, |
1514 bool needsGetter, | 1538 bool needsGetter, |
(...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3275 if (!hasOwnProperty.call(element, prop)) continue; | 3299 if (!hasOwnProperty.call(element, prop)) continue; |
3276 if (prop.substring(0, 1) == "@" && prop != "@") { | 3300 if (prop.substring(0, 1) == "@" && prop != "@") { |
3277 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' | 3301 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' |
3278 '''element[prop]; | 3302 '''element[prop]; |
3279 } else { | 3303 } else { |
3280 newDesc[prop] = element[prop]; | 3304 newDesc[prop] = element[prop]; |
3281 } | 3305 } |
3282 } | 3306 } |
3283 $classesCollector[property] = newDesc; | 3307 $classesCollector[property] = newDesc; |
3284 classes.push(property); | 3308 classes.push(property); |
3285 classes.push(element[""]); | |
3286 } | 3309 } |
3287 } | 3310 } |
3288 libraries.push([name, uri, classes, functions, metadata]); | 3311 libraries.push([name, uri, classes, functions, metadata]); |
3289 } | 3312 } |
3290 })'''; | 3313 })'''; |
3291 } | 3314 } |
3292 } | 3315 } |
3293 | 3316 |
3294 const String GENERATED_BY = """ | 3317 const String GENERATED_BY = """ |
3295 // Generated by dart2js, the Dart to JavaScript compiler. | 3318 // Generated by dart2js, the Dart to JavaScript compiler. |
3296 """; | 3319 """; |
3297 | 3320 |
3298 const String HOOKS_API_USAGE = """ | 3321 const String HOOKS_API_USAGE = """ |
3299 // The code supports the following hooks: | 3322 // The code supports the following hooks: |
3300 // dartPrint(message) - if this function is defined it is called | 3323 // dartPrint(message) - if this function is defined it is called |
3301 // instead of the Dart [print] method. | 3324 // instead of the Dart [print] method. |
3302 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3325 // dartMainRunner(main) - if this function is defined, the Dart [main] |
3303 // method will not be invoked directly. | 3326 // method will not be invoked directly. |
3304 // Instead, a closure that will invoke [main] is | 3327 // Instead, a closure that will invoke [main] is |
3305 // passed to [dartMainRunner]. | 3328 // passed to [dartMainRunner]. |
3306 """; | 3329 """; |
OLD | NEW |