Chromium Code Reviews| 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 |