| 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 library dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 } | 498 } |
| 499 | 499 |
| 500 /// Given a class element and body, complete the class declaration. | 500 /// Given a class element and body, complete the class declaration. |
| 501 /// This handles generic type parameters, laziness (in library-cycle cases), | 501 /// This handles generic type parameters, laziness (in library-cycle cases), |
| 502 /// and ensuring dependencies are loaded first. | 502 /// and ensuring dependencies are loaded first. |
| 503 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { | 503 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { |
| 504 var name = type.name; | 504 var name = type.name; |
| 505 var genericName = '$name\$'; | 505 var genericName = '$name\$'; |
| 506 | 506 |
| 507 JS.Statement genericDef = null; | 507 JS.Statement genericDef = null; |
| 508 if (_boundTypeParametersOf(type).isNotEmpty) { | 508 if (_typeFormalsOf(type).isNotEmpty) { |
| 509 genericDef = _emitGenericClassDef(type, body); | 509 genericDef = _emitGenericClassDef(type, body); |
| 510 } | 510 } |
| 511 // The base class and all mixins must be declared before this class. | 511 // The base class and all mixins must be declared before this class. |
| 512 if (!_loader.isLoaded(type.element)) { | 512 if (!_loader.isLoaded(type.element)) { |
| 513 // TODO(jmesserly): the lazy class def is a simple solution for now. | 513 // TODO(jmesserly): the lazy class def is a simple solution for now. |
| 514 // We may want to consider other options in the future. | 514 // We may want to consider other options in the future. |
| 515 | 515 |
| 516 if (genericDef != null) { | 516 if (genericDef != null) { |
| 517 return js.statement( | 517 return js.statement( |
| 518 '{ #; dart.defineLazyClassGeneric(#, #, { get: # }); }', | 518 '{ #; dart.defineLazyClassGeneric(#, #, { get: # }); }', |
| (...skipping 11 matching lines...) Expand all Loading... |
| 530 var dynType = fillDynamicTypeArgs(type, types); | 530 var dynType = fillDynamicTypeArgs(type, types); |
| 531 var genericInst = _emitTypeName(dynType, lowerGeneric: true); | 531 var genericInst = _emitTypeName(dynType, lowerGeneric: true); |
| 532 return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); | 532 return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); |
| 533 } | 533 } |
| 534 return body; | 534 return body; |
| 535 } | 535 } |
| 536 | 536 |
| 537 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { | 537 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { |
| 538 var name = type.name; | 538 var name = type.name; |
| 539 var genericName = '$name\$'; | 539 var genericName = '$name\$'; |
| 540 var typeParams = _boundTypeParametersOf(type).map((p) => p.name); | 540 var typeParams = _typeFormalsOf(type).map((p) => p.name); |
| 541 if (isPublic(name)) _exports.add(genericName); | 541 if (isPublic(name)) _exports.add(genericName); |
| 542 return js.statement('const # = dart.generic(function(#) { #; return #; });', | 542 return js.statement('const # = dart.generic(function(#) { #; return #; });', |
| 543 [genericName, typeParams, body, name]); | 543 [genericName, typeParams, body, name]); |
| 544 } | 544 } |
| 545 | 545 |
| 546 final _hasDeferredSupertype = new HashSet<ClassElement>(); | 546 final _hasDeferredSupertype = new HashSet<ClassElement>(); |
| 547 | 547 |
| 548 bool _deferIfNeeded(DartType type, ClassElement current) { | 548 bool _deferIfNeeded(DartType type, ClassElement current) { |
| 549 if (type is ParameterizedType) { | 549 if (type is ParameterizedType) { |
| 550 var typeArguments = type.typeArguments; | 550 var typeArguments = type.typeArguments; |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 var accessor = node.staticElement; | 1549 var accessor = node.staticElement; |
| 1550 if (accessor == null) { | 1550 if (accessor == null) { |
| 1551 return js.commentExpression( | 1551 return js.commentExpression( |
| 1552 'Unimplemented unknown name', new JS.Identifier(node.name)); | 1552 'Unimplemented unknown name', new JS.Identifier(node.name)); |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 // Get the original declaring element. If we had a property accessor, this | 1555 // Get the original declaring element. If we had a property accessor, this |
| 1556 // indirects back to a (possibly synthetic) field. | 1556 // indirects back to a (possibly synthetic) field. |
| 1557 var element = accessor; | 1557 var element = accessor; |
| 1558 if (accessor is PropertyAccessorElement) element = accessor.variable; | 1558 if (accessor is PropertyAccessorElement) element = accessor.variable; |
| 1559 if (accessor is FunctionMember) element = accessor.baseElement; | |
| 1560 | 1559 |
| 1561 _loader.declareBeforeUse(element); | 1560 _loader.declareBeforeUse(element); |
| 1562 | 1561 |
| 1563 // type literal | 1562 // type literal |
| 1564 if (element is ClassElement || | 1563 if (element is ClassElement || |
| 1565 element is DynamicElementImpl || | 1564 element is DynamicElementImpl || |
| 1566 element is FunctionTypeAliasElement) { | 1565 element is FunctionTypeAliasElement) { |
| 1567 return _emitTypeName( | 1566 return _emitTypeName( |
| 1568 fillDynamicTypeArgs((element as dynamic).type, types)); | 1567 fillDynamicTypeArgs((element as dynamic).type, types)); |
| 1569 } | 1568 } |
| (...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3255 } | 3254 } |
| 3256 | 3255 |
| 3257 /// Visits a list of expressions, creating a comma expression if needed in JS. | 3256 /// Visits a list of expressions, creating a comma expression if needed in JS. |
| 3258 JS.Expression _visitListToBinary(List<Expression> nodes, String operator) { | 3257 JS.Expression _visitListToBinary(List<Expression> nodes, String operator) { |
| 3259 if (nodes == null || nodes.isEmpty) return null; | 3258 if (nodes == null || nodes.isEmpty) return null; |
| 3260 return new JS.Expression.binary( | 3259 return new JS.Expression.binary( |
| 3261 _visitList(nodes) as List<JS.Expression>, operator); | 3260 _visitList(nodes) as List<JS.Expression>, operator); |
| 3262 } | 3261 } |
| 3263 | 3262 |
| 3264 /// Return the bound type parameters for a ParameterizedType | 3263 /// Return the bound type parameters for a ParameterizedType |
| 3265 List<TypeParameterElement> _boundTypeParametersOf(ParameterizedType type) { | 3264 List<TypeParameterElement> _typeFormalsOf(ParameterizedType type) { |
| 3266 return (type is FunctionType) | 3265 return type is FunctionType ? type.typeFormals : type.typeParameters; |
| 3267 ? type.boundTypeParameters | |
| 3268 : type.typeParameters; | |
| 3269 } | 3266 } |
| 3270 | 3267 |
| 3271 /// Like [_emitMemberName], but for declaration sites. | 3268 /// Like [_emitMemberName], but for declaration sites. |
| 3272 /// | 3269 /// |
| 3273 /// Unlike call sites, we always have an element available, so we can use it | 3270 /// Unlike call sites, we always have an element available, so we can use it |
| 3274 /// directly rather than computing the relevant options for [_emitMemberName]. | 3271 /// directly rather than computing the relevant options for [_emitMemberName]. |
| 3275 JS.Expression _elementMemberName(ExecutableElement e, | 3272 JS.Expression _elementMemberName(ExecutableElement e, |
| 3276 {bool allowExtensions: true}) { | 3273 {bool allowExtensions: true}) { |
| 3277 String name; | 3274 String name; |
| 3278 if (e is PropertyAccessorElement) { | 3275 if (e is PropertyAccessorElement) { |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3552 | 3549 |
| 3553 /// A special kind of element created by the compiler, signifying a temporary | 3550 /// A special kind of element created by the compiler, signifying a temporary |
| 3554 /// variable. These objects use instance equality, and should be shared | 3551 /// variable. These objects use instance equality, and should be shared |
| 3555 /// everywhere in the tree where they are treated as the same variable. | 3552 /// everywhere in the tree where they are treated as the same variable. |
| 3556 class TemporaryVariableElement extends LocalVariableElementImpl { | 3553 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3557 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3554 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3558 | 3555 |
| 3559 int get hashCode => identityHashCode(this); | 3556 int get hashCode => identityHashCode(this); |
| 3560 bool operator ==(Object other) => identical(this, other); | 3557 bool operator ==(Object other) => identical(this, other); |
| 3561 } | 3558 } |
| OLD | NEW |