| 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 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
| 7 | 7 |
| 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 822 |
| 823 // Create static fields for each enum value | 823 // Create static fields for each enum value |
| 824 for (var i = 0; i < fields.length; ++i) { | 824 for (var i = 0; i < fields.length; ++i) { |
| 825 result.add(js.statement('#.# = dart.const(new #(#));', | 825 result.add(js.statement('#.# = dart.const(new #(#));', |
| 826 [id, fields[i].name, id, js.number(i)])); | 826 [id, fields[i].name, id, js.number(i)])); |
| 827 } | 827 } |
| 828 | 828 |
| 829 // Create static values list | 829 // Create static values list |
| 830 var values = new JS.ArrayInitializer(new List<JS.Expression>.from( | 830 var values = new JS.ArrayInitializer(new List<JS.Expression>.from( |
| 831 fields.map((f) => js.call('#.#', [id, f.name])))); | 831 fields.map((f) => js.call('#.#', [id, f.name])))); |
| 832 result.add(js.statement('#.values = dart.const(dart.list(#, #));', | 832 result.add(js.statement('#.values = dart.constList(#, #);', |
| 833 [id, values, _emitType(type)])); | 833 [id, values, _emitType(type)])); |
| 834 | 834 |
| 835 return _statement(result); | 835 return _statement(result); |
| 836 } | 836 } |
| 837 | 837 |
| 838 /// Wraps a possibly generic class in its type arguments. | 838 /// Wraps a possibly generic class in its type arguments. |
| 839 JS.Statement _defineClassTypeArguments(TypeDefiningElement element, | 839 JS.Statement _defineClassTypeArguments(TypeDefiningElement element, |
| 840 List<TypeParameterElement> formals, JS.Statement body) { | 840 List<TypeParameterElement> formals, JS.Statement body) { |
| 841 assert(formals.isNotEmpty); | 841 assert(formals.isNotEmpty); |
| 842 var genericCall = js.call('dart.generic((#) => { #; return #; })', | 842 var genericCall = js.call('dart.generic((#) => { #; return #; })', |
| (...skipping 2583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3426 | 3426 |
| 3427 variable ??= new JS.TemporaryId(name); | 3427 variable ??= new JS.TemporaryId(name); |
| 3428 | 3428 |
| 3429 id.staticElement = new TemporaryVariableElement.forNode(id, variable); | 3429 id.staticElement = new TemporaryVariableElement.forNode(id, variable); |
| 3430 id.staticType = type; | 3430 id.staticType = type; |
| 3431 DynamicInvoke.set(id, type.isDynamic); | 3431 DynamicInvoke.set(id, type.isDynamic); |
| 3432 addTemporaryVariable(id.staticElement, nullable: nullable); | 3432 addTemporaryVariable(id.staticElement, nullable: nullable); |
| 3433 return id; | 3433 return id; |
| 3434 } | 3434 } |
| 3435 | 3435 |
| 3436 JS.Expression _emitConst(JS.Expression expr()) { | 3436 JS.Expression _cacheConst(JS.Expression expr()) { |
| 3437 var savedTypeParams = _typeParamInConst; | 3437 var savedTypeParams = _typeParamInConst; |
| 3438 _typeParamInConst = []; | 3438 _typeParamInConst = []; |
| 3439 | 3439 |
| 3440 var jsExpr = js.call('dart.const(#)', expr()); | 3440 var jsExpr = expr(); |
| 3441 | 3441 |
| 3442 bool usesTypeParams = _typeParamInConst.isNotEmpty; | 3442 bool usesTypeParams = _typeParamInConst.isNotEmpty; |
| 3443 _typeParamInConst = savedTypeParams; | 3443 _typeParamInConst = savedTypeParams; |
| 3444 | 3444 |
| 3445 // TODO(jmesserly): if it uses type params we can still hoist it up as far | 3445 // TODO(jmesserly): if it uses type params we can still hoist it up as far |
| 3446 // as it will go, e.g. at the level the generic class is defined where type | 3446 // as it will go, e.g. at the level the generic class is defined where type |
| 3447 // params are available. | 3447 // params are available. |
| 3448 if (_currentFunction == null || usesTypeParams) return jsExpr; | 3448 if (_currentFunction == null || usesTypeParams) return jsExpr; |
| 3449 | 3449 |
| 3450 var temp = new JS.TemporaryId('const'); | 3450 var temp = new JS.TemporaryId('const'); |
| 3451 _moduleItems.add(js.statement('let #;', [temp])); | 3451 _moduleItems.add(js.statement('let #;', [temp])); |
| 3452 return js.call('# || (# = #)', [temp, temp, jsExpr]); | 3452 return js.call('# || (# = #)', [temp, temp, jsExpr]); |
| 3453 } | 3453 } |
| 3454 |
| 3455 JS.Expression _emitConst(JS.Expression expr()) => |
| 3456 _cacheConst(() => js.call('dart.const(#)', expr())); |
| 3454 | 3457 |
| 3455 /// Returns a new expression, which can be be used safely *once* on the | 3458 /// Returns a new expression, which can be be used safely *once* on the |
| 3456 /// left hand side, and *once* on the right side of an assignment. | 3459 /// left hand side, and *once* on the right side of an assignment. |
| 3457 /// For example: `expr1[expr2] += y` can be compiled as | 3460 /// For example: `expr1[expr2] += y` can be compiled as |
| 3458 /// `expr1[expr2] = expr1[expr2] + y`. | 3461 /// `expr1[expr2] = expr1[expr2] + y`. |
| 3459 /// | 3462 /// |
| 3460 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated | 3463 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated |
| 3461 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`. | 3464 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`. |
| 3462 /// | 3465 /// |
| 3463 /// If the expression does not end up using `x1` or `x2` more than once, or | 3466 /// If the expression does not end up using `x1` or `x2` more than once, or |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4149 // TODO(vsm): When we canonicalize, we need to treat private symbols | 4152 // TODO(vsm): When we canonicalize, we need to treat private symbols |
| 4150 // correctly. | 4153 // correctly. |
| 4151 var name = js.string(node.components.join('.'), "'"); | 4154 var name = js.string(node.components.join('.'), "'"); |
| 4152 return js.call('#.new(#)', [_emitType(types.symbolType), name]); | 4155 return js.call('#.new(#)', [_emitType(types.symbolType), name]); |
| 4153 } | 4156 } |
| 4154 return _emitConst(emitSymbol); | 4157 return _emitConst(emitSymbol); |
| 4155 } | 4158 } |
| 4156 | 4159 |
| 4157 @override | 4160 @override |
| 4158 visitListLiteral(ListLiteral node) { | 4161 visitListLiteral(ListLiteral node) { |
| 4162 var isConst = node.constKeyword != null; |
| 4159 JS.Expression emitList() { | 4163 JS.Expression emitList() { |
| 4160 JS.Expression list = new JS.ArrayInitializer( | 4164 JS.Expression list = new JS.ArrayInitializer( |
| 4161 _visitList(node.elements) as List<JS.Expression>); | 4165 _visitList(node.elements) as List<JS.Expression>); |
| 4162 ParameterizedType type = node.staticType; | 4166 ParameterizedType type = node.staticType; |
| 4163 var elementType = type.typeArguments.single; | 4167 var elementType = type.typeArguments.single; |
| 4164 // TODO(jmesserly): analyzer will usually infer `List<Object>` because | 4168 // TODO(jmesserly): analyzer will usually infer `List<Object>` because |
| 4165 // that is the least upper bound of the element types. So we rarely | 4169 // that is the least upper bound of the element types. So we rarely |
| 4166 // generate a plain `List<dynamic>` anymore. | 4170 // generate a plain `List<dynamic>` anymore. |
| 4167 if (!elementType.isDynamic) { | 4171 if (!elementType.isDynamic || isConst) { |
| 4168 // dart.list helper internally depends on _interceptors.JSArray. | 4172 // dart.list helper internally depends on _interceptors.JSArray. |
| 4169 _declareBeforeUse(_jsArray); | 4173 _declareBeforeUse(_jsArray); |
| 4170 list = js.call('dart.list(#, #)', [list, _emitType(elementType)]); | 4174 var typeRep = _emitType(elementType); |
| 4175 var helper = (isConst) ? 'constList' : 'list'; |
| 4176 list = js.call('dart.${helper}(#, #)', [list, typeRep]); |
| 4171 } | 4177 } |
| 4172 return list; | 4178 return list; |
| 4173 } | 4179 } |
| 4174 if (node.constKeyword != null) return _emitConst(emitList); | 4180 if (isConst) return _cacheConst(emitList); |
| 4175 return emitList(); | 4181 return emitList(); |
| 4176 } | 4182 } |
| 4177 | 4183 |
| 4178 @override | 4184 @override |
| 4179 visitMapLiteral(MapLiteral node) { | 4185 visitMapLiteral(MapLiteral node) { |
| 4180 // TODO(jmesserly): we can likely make these faster. | 4186 // TODO(jmesserly): we can likely make these faster. |
| 4181 JS.Expression emitMap() { | 4187 JS.Expression emitMap() { |
| 4182 var entries = node.entries; | 4188 var entries = node.entries; |
| 4183 var mapArguments = null; | 4189 var mapArguments = null; |
| 4184 var typeArgs = node.typeArguments; | 4190 var typeArgs = node.typeArguments; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4557 } | 4563 } |
| 4558 | 4564 |
| 4559 bool isLibraryPrefix(Expression node) => | 4565 bool isLibraryPrefix(Expression node) => |
| 4560 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4566 node is SimpleIdentifier && node.staticElement is PrefixElement; |
| 4561 | 4567 |
| 4562 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4568 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
| 4563 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4569 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
| 4564 | 4570 |
| 4565 bool _isDartRuntime(LibraryElement l) => | 4571 bool _isDartRuntime(LibraryElement l) => |
| 4566 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4572 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
| OLD | NEW |