Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 16156013: Implement metadata for instance fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Found an issue during testing. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/sdk/lib/_internal/compiler/implementation/lib/js_mirrors.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 """;
OLDNEW
« no previous file with comments | « no previous file | dart/sdk/lib/_internal/compiler/implementation/lib/js_mirrors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698