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 | 2 |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 } | 1877 } |
1878 return members; | 1878 return members; |
1879 } | 1879 } |
1880 | 1880 |
1881 /// Generates the implicit default constructor for class C of the form | 1881 /// Generates the implicit default constructor for class C of the form |
1882 /// `C() : super() {}`. | 1882 /// `C() : super() {}`. |
1883 JS.Method _emitImplicitConstructor( | 1883 JS.Method _emitImplicitConstructor( |
1884 ClassDeclaration node, | 1884 ClassDeclaration node, |
1885 List<FieldDeclaration> fields, | 1885 List<FieldDeclaration> fields, |
1886 Map<FieldElement, JS.TemporaryId> virtualFields) { | 1886 Map<FieldElement, JS.TemporaryId> virtualFields) { |
1887 assert(_hasUnnamedConstructor(node.element) == fields.isNotEmpty); | |
1888 | |
1889 // If we don't have a method body, skip this. | 1887 // If we don't have a method body, skip this. |
1890 var superCall = _superConstructorCall(node.element); | 1888 var superCall = _superConstructorCall(node.element); |
1891 if (fields.isEmpty && superCall == null) return null; | 1889 if (fields.isEmpty && superCall == null) return null; |
1892 | 1890 |
1893 var initFields = _initializeFields(node, fields, virtualFields); | 1891 var initFields = _initializeFields(node, fields, virtualFields); |
1894 List<JS.Statement> body = [initFields]; | 1892 List<JS.Statement> body = [initFields]; |
1895 if (superCall != null) { | 1893 if (superCall != null) { |
1896 body.add(superCall); | 1894 body.add(superCall); |
1897 } | 1895 } |
1898 var name = _constructorName(node.element.unnamedConstructor); | 1896 var name = _constructorName(node.element.unnamedConstructor); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 } | 2050 } |
2053 | 2051 |
2054 if (superCtor == null) { | 2052 if (superCtor == null) { |
2055 // This will only happen if the code has errors: | 2053 // This will only happen if the code has errors: |
2056 // we're trying to generate an implicit constructor for a type where | 2054 // we're trying to generate an implicit constructor for a type where |
2057 // we don't have a default constructor in the supertype. | 2055 // we don't have a default constructor in the supertype. |
2058 assert(options.unsafeForceCompile); | 2056 assert(options.unsafeForceCompile); |
2059 return null; | 2057 return null; |
2060 } | 2058 } |
2061 | 2059 |
2062 if (superCtor.name == '' && !_shouldCallUnnamedSuperCtor(element)) { | 2060 if (superCtor.name == '' && !_hasUnnamedSuperConstructor(element)) { |
2063 return null; | 2061 return null; |
2064 } | 2062 } |
2065 | 2063 |
2066 var name = _constructorName(superCtor); | 2064 var name = _constructorName(superCtor); |
2067 var args = node != null ? _visit(node.argumentList) : []; | 2065 var args = node != null ? _visit(node.argumentList) : []; |
2068 return annotate(js.statement('super.#(#);', [name, args]), node); | 2066 return annotate(js.statement('super.#(#);', [name, args]), node); |
2069 } | 2067 } |
2070 | 2068 |
2071 bool _shouldCallUnnamedSuperCtor(ClassElement e) { | 2069 bool _hasUnnamedSuperConstructor(ClassElement e) { |
2072 var supertype = e.supertype; | 2070 var supertype = e.supertype; |
2073 if (supertype == null) return false; | 2071 if (supertype == null) return false; |
2074 if (_hasUnnamedConstructor(supertype.element)) return true; | 2072 if (_hasUnnamedConstructor(supertype.element)) return true; |
2075 for (var mixin in e.mixins) { | 2073 for (var mixin in e.mixins) { |
2076 if (_hasUnnamedConstructor(mixin.element)) return true; | 2074 if (_hasUnnamedConstructor(mixin.element)) return true; |
2077 } | 2075 } |
2078 return false; | 2076 return false; |
2079 } | 2077 } |
2080 | 2078 |
2081 bool _hasUnnamedConstructor(ClassElement e) { | 2079 bool _hasUnnamedConstructor(ClassElement e) { |
2082 if (e.type.isObject) return false; | 2080 if (e.type.isObject) return false; |
2083 if (!e.unnamedConstructor.isSynthetic) return true; | 2081 if (!e.unnamedConstructor.isSynthetic) return true; |
2084 return e.fields.any((f) => !f.isStatic && !f.isSynthetic); | 2082 if (e.fields.any((f) => !f.isStatic && !f.isSynthetic)) return true; |
| 2083 return _hasUnnamedSuperConstructor(e); |
2085 } | 2084 } |
2086 | 2085 |
2087 /// Initialize fields. They follow the sequence: | 2086 /// Initialize fields. They follow the sequence: |
2088 /// | 2087 /// |
2089 /// 1. field declaration initializer if non-const, | 2088 /// 1. field declaration initializer if non-const, |
2090 /// 2. field initializing parameters, | 2089 /// 2. field initializing parameters, |
2091 /// 3. constructor field initializers, | 2090 /// 3. constructor field initializers, |
2092 /// 4. initialize fields not covered in 1-3 | 2091 /// 4. initialize fields not covered in 1-3 |
2093 JS.Statement _initializeFields( | 2092 JS.Statement _initializeFields( |
2094 ClassDeclaration cls, | 2093 ClassDeclaration cls, |
(...skipping 3393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5488 } | 5487 } |
5489 | 5488 |
5490 bool isLibraryPrefix(Expression node) => | 5489 bool isLibraryPrefix(Expression node) => |
5491 node is SimpleIdentifier && node.staticElement is PrefixElement; | 5490 node is SimpleIdentifier && node.staticElement is PrefixElement; |
5492 | 5491 |
5493 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 5492 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
5494 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 5493 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
5495 | 5494 |
5496 bool _isDartRuntime(LibraryElement l) => | 5495 bool _isDartRuntime(LibraryElement l) => |
5497 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 5496 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |