| 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 library dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap; | 7 import 'dart:collection' show HashSet, HashMap; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 return js.statement('dart.virtualField(#, #)', [ | 644 return js.statement('dart.virtualField(#, #)', [ |
| 645 cls.name, | 645 cls.name, |
| 646 _emitMemberName(e.name, type: cls.type) | 646 _emitMemberName(e.name, type: cls.type) |
| 647 ]); | 647 ]); |
| 648 } | 648 } |
| 649 | 649 |
| 650 /// Generates the implicit default constructor for class C of the form | 650 /// Generates the implicit default constructor for class C of the form |
| 651 /// `C() : super() {}`. | 651 /// `C() : super() {}`. |
| 652 JS.Method _emitImplicitConstructor( | 652 JS.Method _emitImplicitConstructor( |
| 653 ClassDeclaration node, String name, List<FieldDeclaration> fields) { | 653 ClassDeclaration node, String name, List<FieldDeclaration> fields) { |
| 654 assert(_hasUnnamedConstructor(node.element) == fields.isNotEmpty); |
| 655 |
| 654 // If we don't have a method body, skip this. | 656 // If we don't have a method body, skip this. |
| 655 if (fields.isEmpty) return null; | 657 if (fields.isEmpty) return null; |
| 656 | 658 |
| 657 dynamic body = _initializeFields(fields); | 659 dynamic body = _initializeFields(fields); |
| 658 var superCall = _superConstructorCall(node); | 660 var superCall = _superConstructorCall(node); |
| 659 if (superCall != null) body = [[body, superCall]]; | 661 if (superCall != null) body = [[body, superCall]]; |
| 660 return new JS.Method( | 662 return new JS.Method( |
| 661 _propertyName(name), js.call('function() { #; }', body)); | 663 _propertyName(name), js.call('function() { #; }', body)); |
| 662 } | 664 } |
| 663 | 665 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 | 770 |
| 769 var name = _constructorName(className, node.constructorName); | 771 var name = _constructorName(className, node.constructorName); |
| 770 return js.statement('this.#(#);', [name, _visit(node.argumentList)]); | 772 return js.statement('this.#(#);', [name, _visit(node.argumentList)]); |
| 771 } | 773 } |
| 772 | 774 |
| 773 JS.Statement _superConstructorCall(ClassDeclaration clazz, | 775 JS.Statement _superConstructorCall(ClassDeclaration clazz, |
| 774 [SuperConstructorInvocation node]) { | 776 [SuperConstructorInvocation node]) { |
| 775 var superCtorName = node != null ? node.constructorName : null; | 777 var superCtorName = node != null ? node.constructorName : null; |
| 776 | 778 |
| 777 var element = clazz.element; | 779 var element = clazz.element; |
| 778 if (superCtorName == null && | 780 if (superCtorName == null && !_shouldCallUnnamedSuperCtor(element)) { |
| 779 (element.type.isObject || element.supertype.isObject)) { | |
| 780 return null; | 781 return null; |
| 781 } | 782 } |
| 782 | 783 |
| 783 var supertypeName = element.supertype.name; | 784 var supertypeName = element.supertype.name; |
| 784 var name = _constructorName(supertypeName, superCtorName); | 785 var name = _constructorName(supertypeName, superCtorName); |
| 785 | 786 |
| 786 var args = node != null ? _visit(node.argumentList) : []; | 787 var args = node != null ? _visit(node.argumentList) : []; |
| 787 return js.statement('super.#(#);', [name, args])..sourceInformation = node; | 788 return js.statement('super.#(#);', [name, args])..sourceInformation = node; |
| 788 } | 789 } |
| 789 | 790 |
| 791 bool _shouldCallUnnamedSuperCtor(ClassElement e) { |
| 792 var supertype = e.supertype; |
| 793 if (supertype == null) return false; |
| 794 if (_hasUnnamedConstructor(supertype.element)) return true; |
| 795 for (var mixin in e.mixins) { |
| 796 if (_hasUnnamedConstructor(mixin.element)) return true; |
| 797 } |
| 798 return false; |
| 799 } |
| 800 |
| 801 bool _hasUnnamedConstructor(ClassElement e) { |
| 802 if (e.type.isObject) return false; |
| 803 if (!e.unnamedConstructor.isSynthetic) return true; |
| 804 return e.fields.any((f) => !f.isStatic && !f.isSynthetic); |
| 805 } |
| 806 |
| 790 /// Initialize fields. They follow the sequence: | 807 /// Initialize fields. They follow the sequence: |
| 791 /// | 808 /// |
| 792 /// 1. field declaration initializer if non-const, | 809 /// 1. field declaration initializer if non-const, |
| 793 /// 2. field initializing parameters, | 810 /// 2. field initializing parameters, |
| 794 /// 3. constructor field initializers, | 811 /// 3. constructor field initializers, |
| 795 /// 4. initialize fields not covered in 1-3 | 812 /// 4. initialize fields not covered in 1-3 |
| 796 JS.Statement _initializeFields(List<FieldDeclaration> fieldDecls, | 813 JS.Statement _initializeFields(List<FieldDeclaration> fieldDecls, |
| 797 [FormalParameterList parameters, | 814 [FormalParameterList parameters, |
| 798 NodeList<ConstructorInitializer> initializers]) { | 815 NodeList<ConstructorInitializer> initializers]) { |
| 799 | 816 |
| (...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 return filepath; | 2386 return filepath; |
| 2370 } | 2387 } |
| 2371 | 2388 |
| 2372 // TODO(jmesserly): validate the library. See issue #135. | 2389 // TODO(jmesserly): validate the library. See issue #135. |
| 2373 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; | 2390 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; |
| 2374 | 2391 |
| 2375 // TODO(jacobr): we would like to do something like the following | 2392 // TODO(jacobr): we would like to do something like the following |
| 2376 // but we don't have summary support yet. | 2393 // but we don't have summary support yet. |
| 2377 // bool _supportJsExtensionMethod(AnnotatedNode node) => | 2394 // bool _supportJsExtensionMethod(AnnotatedNode node) => |
| 2378 // _getAnnotation(node, "SupportJsExtensionMethod") != null; | 2395 // _getAnnotation(node, "SupportJsExtensionMethod") != null; |
| OLD | NEW |