| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.startup_emitter.model_emitter; | 5 part of dart2js.js_emitter.startup_emitter.model_emitter; |
| 6 | 6 |
| 7 /// The name of the property that stores the tear-off getter on a static | 7 /// The name of the property that stores the tear-off getter on a static |
| 8 /// function. | 8 /// function. |
| 9 /// | 9 /// |
| 10 /// This property is only used when isolates are used. | 10 /// This property is only used when isolates are used. |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 /// | 646 /// |
| 647 /// The constructor is statically built. | 647 /// The constructor is statically built. |
| 648 js.Expression emitConstructor(Class cls) { | 648 js.Expression emitConstructor(Class cls) { |
| 649 js.Name name = cls.name; | 649 js.Name name = cls.name; |
| 650 // If the class is not directly instantiated we only need it for inheritance | 650 // If the class is not directly instantiated we only need it for inheritance |
| 651 // or RTI. In either case we don't need its fields. | 651 // or RTI. In either case we don't need its fields. |
| 652 if (cls.isNative || !cls.isDirectlyInstantiated) { | 652 if (cls.isNative || !cls.isDirectlyInstantiated) { |
| 653 return js.js('function #() { }', name); | 653 return js.js('function #() { }', name); |
| 654 } | 654 } |
| 655 | 655 |
| 656 List<js.Name> fieldNames = | 656 var statements = <js.Statement>[]; |
| 657 cls.fields.map((Field field) => field.name).toList(); | 657 var parameters = <js.Name>[]; |
| 658 if (cls.hasRtiField) { | 658 var thisRef; |
| 659 fieldNames.add(namer.rtiFieldJsName); | 659 |
| 660 // If there are many references to `this`, cache it in a local. |
| 661 if (cls.fields.length + (cls.hasRtiField ? 1 : 0) >= 4) { |
| 662 // TODO(29455): Fix js_ast printer and minifier to avoid conflicts between |
| 663 // js.Name and string-named variables, then use '_' in the js template |
| 664 // text. |
| 665 |
| 666 // We pick '_' in minified mode because no field minifies to '_'. This |
| 667 // avoids a conflict with one of the parameters which are named the same |
| 668 // as the fields. Unminified, a field might have the name '_', so we pick |
| 669 // '$_', which is an impossible member name since we escape '$'s in names. |
| 670 js.Name underscore = compiler.options.enableMinification |
| 671 ? new StringBackedName('_') |
| 672 : new StringBackedName(r'$_'); |
| 673 statements.add(js.js.statement('var # = this;', underscore)); |
| 674 thisRef = underscore; |
| 675 } else { |
| 676 thisRef = js.js('this'); |
| 660 } | 677 } |
| 661 | 678 |
| 662 Iterable<js.Name> assignments = fieldNames.map((js.Name field) { | 679 for (Field field in cls.fields) { |
| 663 return js.js("this.#field = #field", {"field": field}); | 680 js.Name paramName = field.name; |
| 664 }); | 681 parameters.add(paramName); |
| 682 statements |
| 683 .add(js.js.statement('#.# = #', [thisRef, field.name, paramName])); |
| 684 } |
| 665 | 685 |
| 666 // TODO(sra): Cache 'this' in a one-character local for 4 or more uses of | 686 if (cls.hasRtiField) { |
| 667 // 'this'. i.e. "var _=this;_.a=a;_.b=b;..." | 687 js.Name paramName = namer.rtiFieldJsName; |
| 688 parameters.add(paramName); |
| 689 statements.add(js.js |
| 690 .statement('#.# = #', [thisRef, namer.rtiFieldJsName, paramName])); |
| 691 } |
| 668 | 692 |
| 669 // TODO(sra): Separate field and field initializer parameter names so the | 693 return js.js('function #(#) { # }', [name, parameters, statements]); |
| 670 // latter may be fully minified. | |
| 671 | |
| 672 return js.js('function #(#) { # }', [name, fieldNames, assignments]); | |
| 673 } | 694 } |
| 674 | 695 |
| 675 /// Emits the prototype-section of the fragment. | 696 /// Emits the prototype-section of the fragment. |
| 676 /// | 697 /// |
| 677 /// This section updates the prototype-property of all constructors in the | 698 /// This section updates the prototype-property of all constructors in the |
| 678 /// global holders. | 699 /// global holders. |
| 679 js.Statement emitPrototypes(Fragment fragment) { | 700 js.Statement emitPrototypes(Fragment fragment) { |
| 680 List<js.Statement> assignments = fragment.libraries | 701 List<js.Statement> assignments = fragment.libraries |
| 681 .expand((Library library) => library.classes) | 702 .expand((Library library) => library.classes) |
| 682 .map((Class cls) { | 703 .map((Class cls) { |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 } | 1466 } |
| 1446 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1467 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
| 1447 js.objectLiteral(interceptorsByTag))); | 1468 js.objectLiteral(interceptorsByTag))); |
| 1448 statements.add( | 1469 statements.add( |
| 1449 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); | 1470 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); |
| 1450 statements.addAll(subclassAssignments); | 1471 statements.addAll(subclassAssignments); |
| 1451 | 1472 |
| 1452 return wrapPhase('nativeSupport', new js.Block(statements)); | 1473 return wrapPhase('nativeSupport', new js.Block(statements)); |
| 1453 } | 1474 } |
| 1454 } | 1475 } |
| OLD | NEW |