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 HashSet, HashMap, SplayTreeSet; | 5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
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'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/visitor.dart'; | 10 import 'package:analyzer/dart/element/visitor.dart'; |
11 import 'package:analyzer/dart/element/type.dart'; | 11 import 'package:analyzer/dart/element/type.dart'; |
12 import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator; | 12 import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator; |
13 import 'package:analyzer/src/generated/constant.dart'; | 13 import 'package:analyzer/src/generated/constant.dart'; |
14 //TODO(leafp): Remove deprecated dependency | 14 //TODO(leafp): Remove deprecated dependency |
15 //ignore: DEPRECATED_MEMBER_USE | 15 //ignore: DEPRECATED_MEMBER_USE |
16 import 'package:analyzer/src/generated/element.dart' | 16 import 'package:analyzer/src/generated/element.dart' |
17 show DynamicElementImpl, DynamicTypeImpl, LocalVariableElementImpl; | 17 show DynamicElementImpl, DynamicTypeImpl, LocalVariableElementImpl; |
18 // TODO(jmesserly): we can remove this when ResolutionCopier is fixed. | |
19 import 'package:analyzer/src/dart/ast/ast.dart' show FunctionBodyImpl; | |
20 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 18 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
21 import 'package:analyzer/src/generated/parser.dart' show ResolutionCopier; | |
22 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 19 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
23 import 'package:analyzer/src/dart/ast/token.dart' | 20 import 'package:analyzer/src/dart/ast/token.dart' |
24 show StringToken, Token, TokenType; | 21 show StringToken, Token, TokenType; |
25 import 'package:analyzer/src/generated/type_system.dart' | 22 import 'package:analyzer/src/generated/type_system.dart' |
26 show StrongTypeSystemImpl; | 23 show StrongTypeSystemImpl; |
27 import 'package:analyzer/src/task/strong/info.dart'; | 24 import 'package:analyzer/src/task/strong/info.dart'; |
28 | 25 |
29 import 'ast_builder.dart' show AstBuilder; | 26 import 'ast_builder.dart' show AstBuilder; |
30 import 'reify_coercions.dart' show CoercionReifier, Tuple2; | 27 import 'reify_coercions.dart' show CoercionReifier, Tuple2; |
31 | 28 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 var context = compiler.context; | 128 var context = compiler.context; |
132 var src = context.sourceFactory.forUri('dart:_interceptors'); | 129 var src = context.sourceFactory.forUri('dart:_interceptors'); |
133 var interceptors = context.computeLibraryElement(src); | 130 var interceptors = context.computeLibraryElement(src); |
134 _jsArray = interceptors.getType('JSArray'); | 131 _jsArray = interceptors.getType('JSArray'); |
135 _isDartRuntime = currentLibrary.source.uri.toString() == 'dart:_runtime'; | 132 _isDartRuntime = currentLibrary.source.uri.toString() == 'dart:_runtime'; |
136 } | 133 } |
137 | 134 |
138 TypeProvider get types => _types; | 135 TypeProvider get types => _types; |
139 | 136 |
140 JS.Program emitLibrary(List<CompilationUnit> units) { | 137 JS.Program emitLibrary(List<CompilationUnit> units) { |
141 // Copy the AST before modifying it. | |
142 units = units.map(_cloneCompilationUnit).toList(); | |
143 | |
144 // Modify the AST to make coercions explicit. | 138 // Modify the AST to make coercions explicit. |
145 new CoercionReifier().reify(units); | 139 units = new CoercionReifier().reify(units); |
146 | 140 |
147 units.last.directives.forEach(_visit); | 141 units.last.directives.forEach(_visit); |
148 | 142 |
149 // Rather than directly visit declarations, we instead use [_loader] to | 143 // Rather than directly visit declarations, we instead use [_loader] to |
150 // visit them. It has the ability to sort elements on demand, so | 144 // visit them. It has the ability to sort elements on demand, so |
151 // dependencies between top level items are handled with a minimal | 145 // dependencies between top level items are handled with a minimal |
152 // reordering of the user's input code. The loader will call back into | 146 // reordering of the user's input code. The loader will call back into |
153 // this visitor via [_emitModuleItem] when it's ready to visit the item | 147 // this visitor via [_emitModuleItem] when it's ready to visit the item |
154 // for real. | 148 // for real. |
155 _loader.collectElements(currentLibrary, units); | 149 _loader.collectElements(currentLibrary, units); |
(...skipping 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2339 /// Emits static fields. | 2333 /// Emits static fields. |
2340 /// | 2334 /// |
2341 /// Instance fields are emitted in [_initializeFields]. | 2335 /// Instance fields are emitted in [_initializeFields]. |
2342 /// | 2336 /// |
2343 /// These are generally treated the same as top-level fields, see | 2337 /// These are generally treated the same as top-level fields, see |
2344 /// [visitTopLevelVariableDeclaration]. | 2338 /// [visitTopLevelVariableDeclaration]. |
2345 @override | 2339 @override |
2346 visitFieldDeclaration(FieldDeclaration node) { | 2340 visitFieldDeclaration(FieldDeclaration node) { |
2347 if (!node.isStatic) return; | 2341 if (!node.isStatic) return; |
2348 | 2342 |
2349 for (var f in node.fields.variables) { | 2343 node.fields.variables.forEach(_emitModuleItem); |
Jennifer Messerly
2016/03/28 18:33:17
This is a small cleanup. It's actually what I orig
| |
2350 _loader.loadDeclaration(f, f.element); | |
2351 } | |
2352 } | 2344 } |
2353 | 2345 |
2354 _addExport(String name, [String exportName]) { | 2346 _addExport(String name, [String exportName]) { |
2355 if (_exports.containsKey(name)) { | 2347 if (_exports.containsKey(name)) { |
2356 throw 'Duplicate top level name found: $name'; | 2348 throw 'Duplicate top level name found: $name'; |
2357 } | 2349 } |
2358 _exports[name] = exportName ?? name; | 2350 _exports[name] = exportName ?? name; |
2359 } | 2351 } |
2360 | 2352 |
2361 @override | 2353 @override |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3175 var init = _visit(node.identifier); | 3167 var init = _visit(node.identifier); |
3176 if (init == null) { | 3168 if (init == null) { |
3177 init = js.call('let #', node.loopVariable.identifier.name); | 3169 init = js.call('let #', node.loopVariable.identifier.name); |
3178 } | 3170 } |
3179 return new JS.ForOf(init, _visit(node.iterable), _visitScope(node.body)); | 3171 return new JS.ForOf(init, _visit(node.iterable), _visitScope(node.body)); |
3180 } | 3172 } |
3181 | 3173 |
3182 JS.Statement _emitAwaitFor(ForEachStatement node) { | 3174 JS.Statement _emitAwaitFor(ForEachStatement node) { |
3183 // Emits `await for (var value in stream) ...`, which desugars as: | 3175 // Emits `await for (var value in stream) ...`, which desugars as: |
3184 // | 3176 // |
3185 // var iter = new StreamIterator<T>(stream); | 3177 // var iter = new StreamIterator(stream); |
3186 // try { | 3178 // try { |
3187 // while (await iter.moveNext()) { | 3179 // while (await iter.moveNext()) { |
3188 // var value = iter.current; | 3180 // var value = iter.current; |
3189 // ... | 3181 // ... |
3190 // } | 3182 // } |
3191 // } finally { | 3183 // } finally { |
3192 // await iter.cancel(); | 3184 // await iter.cancel(); |
3193 // } | 3185 // } |
3194 // | 3186 // |
3195 // Like the Dart VM, we call cancel() always, as it's safe to call if the | 3187 // Like the Dart VM, we call cancel() always, as it's safe to call if the |
3196 // stream has already been cancelled. | 3188 // stream has already been cancelled. |
3197 // | 3189 // |
3198 // TODO(jmesserly): we may want a helper if these become common. For now the | 3190 // TODO(jmesserly): we may want a helper if these become common. For now the |
3199 // full desugaring seems okay. | 3191 // full desugaring seems okay. |
3200 var context = compiler.context; | 3192 var context = compiler.context; |
3201 var dart_async = context | 3193 var dart_async = context |
3202 .computeLibraryElement(context.sourceFactory.forUri('dart:async')); | 3194 .computeLibraryElement(context.sourceFactory.forUri('dart:async')); |
3203 var T = node.loopVariable.element.type; | 3195 var _streamIteratorType = |
3204 var StreamIterator_T = | 3196 rules.instantiateToBounds(dart_async.getType('StreamIterator').type); |
3205 dart_async.getType('StreamIterator').type.instantiate([T]); | |
3206 | 3197 |
3207 var createStreamIter = _emitInstanceCreationExpression( | 3198 var createStreamIter = _emitInstanceCreationExpression( |
3208 StreamIterator_T.element.unnamedConstructor, | 3199 _streamIteratorType.element.unnamedConstructor, |
3209 StreamIterator_T, | 3200 _streamIteratorType, |
3210 null, | 3201 null, |
3211 AstBuilder.argumentList([node.iterable]), | 3202 AstBuilder.argumentList([node.iterable]), |
3212 false); | 3203 false); |
3213 var iter = | 3204 var iter = |
3214 _visit(_createTemporary('it', StreamIterator_T, nullable: false)); | 3205 _visit(_createTemporary('it', _streamIteratorType, nullable: false)); |
3215 | 3206 |
3216 var init = _visit(node.identifier); | 3207 var init = _visit(node.identifier); |
3217 if (init == null) { | 3208 if (init == null) { |
3218 init = js | 3209 init = js |
3219 .call('let # = #.current', [node.loopVariable.identifier.name, iter]); | 3210 .call('let # = #.current', [node.loopVariable.identifier.name, iter]); |
3220 } else { | 3211 } else { |
3221 init = js.call('# = #.current', [init, iter]); | 3212 init = js.call('# = #.current', [init, iter]); |
3222 } | 3213 } |
3223 return js.statement( | 3214 return js.statement( |
3224 '{' | 3215 '{' |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3837 | 3828 |
3838 /// A special kind of element created by the compiler, signifying a temporary | 3829 /// A special kind of element created by the compiler, signifying a temporary |
3839 /// variable. These objects use instance equality, and should be shared | 3830 /// variable. These objects use instance equality, and should be shared |
3840 /// everywhere in the tree where they are treated as the same variable. | 3831 /// everywhere in the tree where they are treated as the same variable. |
3841 class TemporaryVariableElement extends LocalVariableElementImpl { | 3832 class TemporaryVariableElement extends LocalVariableElementImpl { |
3842 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3833 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
3843 | 3834 |
3844 int get hashCode => identityHashCode(this); | 3835 int get hashCode => identityHashCode(this); |
3845 bool operator ==(Object other) => identical(this, other); | 3836 bool operator ==(Object other) => identical(this, other); |
3846 } | 3837 } |
3847 | |
3848 CompilationUnit _cloneCompilationUnit(CompilationUnit unit) { | |
3849 var result = new _TreeCloner().visitCompilationUnit(unit); | |
3850 ResolutionCopier.copyResolutionData(unit, result); | |
3851 return result; | |
3852 } | |
3853 | |
3854 class _TreeCloner extends AstCloner { | |
3855 void _cloneProperties(AstNode clone, AstNode node) { | |
3856 if (clone != null) { | |
3857 CoercionInfo.set(clone, CoercionInfo.get(node)); | |
3858 DynamicInvoke.set(clone, DynamicInvoke.get(node)); | |
3859 } | |
3860 } | |
3861 | |
3862 @override | |
3863 AstNode cloneNode(AstNode node) { | |
3864 var clone = super.cloneNode(node); | |
3865 _cloneProperties(clone, node); | |
3866 return clone; | |
3867 } | |
3868 | |
3869 @override | |
3870 List cloneNodeList(List list) { | |
3871 var clone = super.cloneNodeList(list); | |
3872 for (int i = 0, len = list.length; i < len; i++) { | |
3873 _cloneProperties(clone[i], list[i]); | |
3874 } | |
3875 return clone; | |
3876 } | |
3877 | |
3878 // TODO(jmesserly): ResolutionCopier is not copying this yet. | |
3879 @override | |
3880 BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) { | |
3881 var clone = super.visitBlockFunctionBody(node); | |
3882 (clone as FunctionBodyImpl).localVariableInfo = | |
3883 (node as FunctionBodyImpl).localVariableInfo; | |
3884 return clone; | |
3885 } | |
3886 | |
3887 @override | |
3888 ExpressionFunctionBody visitExpressionFunctionBody( | |
3889 ExpressionFunctionBody node) { | |
3890 var clone = super.visitExpressionFunctionBody(node); | |
3891 (clone as FunctionBodyImpl).localVariableInfo = | |
3892 (node as FunctionBodyImpl).localVariableInfo; | |
3893 return clone; | |
3894 } | |
3895 } | |
OLD | NEW |