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 import 'dart:collection' show HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
6 | 6 |
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
8 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 8 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 /// The list of output module items, in the order they need to be emitted in. | 66 /// The list of output module items, in the order they need to be emitted in. |
67 final _moduleItems = <JS.ModuleItem>[]; | 67 final _moduleItems = <JS.ModuleItem>[]; |
68 | 68 |
69 /// The global extension type table. | 69 /// The global extension type table. |
70 final ExtensionTypeSet _extensionTypes; | 70 final ExtensionTypeSet _extensionTypes; |
71 | 71 |
72 /// Information that is precomputed for this library, indicates which fields | 72 /// Information that is precomputed for this library, indicates which fields |
73 /// need storage slots. | 73 /// need storage slots. |
74 HashSet<FieldElement> _fieldsNeedingStorage; | 74 HashSet<FieldElement> _fieldsNeedingStorage; |
75 | 75 |
76 /// Information that indicates which properties are partial overrides of | |
77 /// superclass properties (e.g., getter-only override of a setter or | |
78 /// vice-versa). | |
79 HashSet<FieldElement> _propertyOverrides; | |
Jennifer Messerly
2016/04/20 21:16:39
if following my suggestion in the next file, this
Harry Terkelsen
2016/04/20 23:33:27
Acknowledged.
| |
80 | |
76 /// The variable for the target of the current `..` cascade expression. | 81 /// The variable for the target of the current `..` cascade expression. |
77 /// | 82 /// |
78 /// Usually a [SimpleIdentifier], but it can also be other expressions | 83 /// Usually a [SimpleIdentifier], but it can also be other expressions |
79 /// that are safe to evaluate multiple times, such as `this`. | 84 /// that are safe to evaluate multiple times, such as `this`. |
80 Expression _cascadeTarget; | 85 Expression _cascadeTarget; |
81 | 86 |
82 /// The variable for the current catch clause | 87 /// The variable for the current catch clause |
83 SimpleIdentifier _catchParameter; | 88 SimpleIdentifier _catchParameter; |
84 | 89 |
85 /// In an async* function, this represents the stream controller parameter. | 90 /// In an async* function, this represents the stream controller parameter. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 } | 182 } |
178 | 183 |
179 return new Tuple2(printer.getText(), sourceMap?.build(unit.name + '.js')); | 184 return new Tuple2(printer.getText(), sourceMap?.build(unit.name + '.js')); |
180 } | 185 } |
181 | 186 |
182 JS.Program _emitModule(List<CompilationUnit> compilationUnits) { | 187 JS.Program _emitModule(List<CompilationUnit> compilationUnits) { |
183 if (_moduleItems.isNotEmpty) { | 188 if (_moduleItems.isNotEmpty) { |
184 throw new StateError('Can only call emitModule once.'); | 189 throw new StateError('Can only call emitModule once.'); |
185 } | 190 } |
186 | 191 |
187 _fieldsNeedingStorage = findFieldsNeedingStorage( | 192 _fieldsNeedingStorage = new HashSet<FieldElement>(); |
193 _propertyOverrides = new HashSet<FieldElement>(); | |
194 | |
195 findFieldsNeedingStorage(_fieldsNeedingStorage, _propertyOverrides, | |
188 compilationUnits.map((u) => u.element), _extensionTypes); | 196 compilationUnits.map((u) => u.element), _extensionTypes); |
189 | 197 |
190 // Transform the AST to make coercions explicit. | 198 // Transform the AST to make coercions explicit. |
191 compilationUnits = CoercionReifier.reify(compilationUnits); | 199 compilationUnits = CoercionReifier.reify(compilationUnits); |
192 | 200 |
193 // Initialize our library variables. | 201 // Initialize our library variables. |
194 var items = <JS.ModuleItem>[]; | 202 var items = <JS.ModuleItem>[]; |
195 for (var unit in compilationUnits) { | 203 for (var unit in compilationUnits) { |
196 var library = unit.element.library; | 204 var library = unit.element.library; |
197 if (unit.element != library.definingCompilationUnit) continue; | 205 if (unit.element != library.definingCompilationUnit) continue; |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 | 783 |
776 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; | 784 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; |
777 | 785 |
778 bool hasIterator = false; | 786 bool hasIterator = false; |
779 for (var m in node.members) { | 787 for (var m in node.members) { |
780 if (m is ConstructorDeclaration) { | 788 if (m is ConstructorDeclaration) { |
781 jsMethods.add(_emitConstructor(m, type, fields, isObject)); | 789 jsMethods.add(_emitConstructor(m, type, fields, isObject)); |
782 } else if (m is MethodDeclaration) { | 790 } else if (m is MethodDeclaration) { |
783 jsMethods.add(_emitMethodDeclaration(type, m)); | 791 jsMethods.add(_emitMethodDeclaration(type, m)); |
784 | 792 |
793 var methodElement = m.element; | |
794 if (methodElement is PropertyAccessorElement) { | |
Jennifer Messerly
2016/04/20 21:16:39
it would be good to refactor this into a method
_
Harry Terkelsen
2016/04/20 23:33:27
Done.
| |
795 var fieldElement = methodElement.variable; | |
796 if (_propertyOverrides.contains(fieldElement)) { | |
Jennifer Messerly
2016/04/20 21:16:39
here we can just call make a call to ask if our pr
| |
797 // Generate a corresponding virtual getter / setter. | |
798 var name = _elementMemberName(methodElement, | |
799 allowExtensions: _extensionTypes.contains(type.element)); | |
800 if (m.isGetter) { | |
801 // Generate a setter | |
802 var value = new JS.TemporaryId('value'); | |
803 var fn = new JS.Fun( | |
Jennifer Messerly
2016/04/20 21:16:39
this could be done a bit simpler:
var fn = js.cal
Harry Terkelsen
2016/04/20 23:33:28
Done.
| |
804 [value], js.statement('{ super[#] = #; }', [name, value])); | |
805 jsMethods.add(new JS.Method(name, fn, isSetter: true)); | |
806 } else { | |
807 // Generate a getter | |
808 var fn = | |
Jennifer Messerly
2016/04/20 21:16:39
same here. if using js_ast, I find it's easier to
Harry Terkelsen
2016/04/20 23:33:27
Done.
| |
809 new JS.Fun([], js.statement('{ return super[#]; }', [name])); | |
810 jsMethods.add(new JS.Method(name, fn, isGetter: true)); | |
811 } | |
812 } | |
813 } | |
814 | |
785 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { | 815 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { |
786 hasIterator = true; | 816 hasIterator = true; |
787 jsMethods.add(_emitIterable(type)); | 817 jsMethods.add(_emitIterable(type)); |
788 } | 818 } |
789 } else if (m is FieldDeclaration && _extensionTypes.contains(element)) { | 819 } else if (m is FieldDeclaration && _extensionTypes.contains(element)) { |
790 jsMethods.addAll(_emitNativeFieldAccessors(m)); | 820 jsMethods.addAll(_emitNativeFieldAccessors(m)); |
791 } | 821 } |
792 } | 822 } |
793 | 823 |
794 // If the type doesn't have an `iterator`, but claims to implement Iterable, | 824 // If the type doesn't have an `iterator`, but claims to implement Iterable, |
(...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3757 } | 3787 } |
3758 | 3788 |
3759 bool isLibraryPrefix(Expression node) => | 3789 bool isLibraryPrefix(Expression node) => |
3760 node is SimpleIdentifier && node.staticElement is PrefixElement; | 3790 node is SimpleIdentifier && node.staticElement is PrefixElement; |
3761 | 3791 |
3762 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 3792 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
3763 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 3793 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
3764 | 3794 |
3765 bool _isDartRuntime(LibraryElement l) => | 3795 bool _isDartRuntime(LibraryElement l) => |
3766 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 3796 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |