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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1095683005: fix super ctor logic (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: merge Created 5 years, 8 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
« no previous file with comments | « lib/runtime/dart/convert.js ('k') | test/codegen/expect/fieldtest.js » ('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) 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
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
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
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;
OLDNEW
« no previous file with comments | « lib/runtime/dart/convert.js ('k') | test/codegen/expect/fieldtest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698