| 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; | 7 import 'dart:collection' show HashSet, HashMap; |
| 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 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 /// | 516 /// |
| 517 /// This will return `null` if the adapter was already added on a super type, | 517 /// This will return `null` if the adapter was already added on a super type, |
| 518 /// otherwise it returns the adapter code. | 518 /// otherwise it returns the adapter code. |
| 519 // TODO(jmesserly): should we adapt `Iterator` too? | 519 // TODO(jmesserly): should we adapt `Iterator` too? |
| 520 JS.Method _emitIterable(InterfaceType t) { | 520 JS.Method _emitIterable(InterfaceType t) { |
| 521 // If a parent had an `iterator` (concrete or abstract) or implements | 521 // If a parent had an `iterator` (concrete or abstract) or implements |
| 522 // Iterable, we know the adapter is already there, so we can skip it as a | 522 // Iterable, we know the adapter is already there, so we can skip it as a |
| 523 // simple code size optimization. | 523 // simple code size optimization. |
| 524 var parent = t.lookUpGetterInSuperclass('iterator', t.element.library); | 524 var parent = t.lookUpGetterInSuperclass('iterator', t.element.library); |
| 525 if (parent != null) return null; | 525 if (parent != null) return null; |
| 526 parent = findSupertype(t, _implementsIterable); | 526 var parentType = findSupertype(t, _implementsIterable); |
| 527 if (parent != null) return null; | 527 if (parentType != null) return null; |
| 528 | 528 |
| 529 // Otherwise, emit the adapter method, which wraps the Dart iterator in | 529 // Otherwise, emit the adapter method, which wraps the Dart iterator in |
| 530 // an ES6 iterator. | 530 // an ES6 iterator. |
| 531 return new JS.Method(js.call('$_SYMBOL.iterator'), js.call( | 531 return new JS.Method(js.call('$_SYMBOL.iterator'), js.call( |
| 532 'function() { return new dart.JsIterator(this.#); }', | 532 'function() { return new dart.JsIterator(this.#); }', |
| 533 [_emitMemberName('iterator', type: t)])); | 533 [_emitMemberName('iterator', type: t)])); |
| 534 } | 534 } |
| 535 | 535 |
| 536 /// Emit class members that need to come after the class declaration, such | 536 /// Emit class members that need to come after the class declaration, such |
| 537 /// as static fields. See [_emitClassMethods] for things that are emitted | 537 /// as static fields. See [_emitClassMethods] for things that are emitted |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { | 1132 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { |
| 1133 var accessor = node.staticElement; | 1133 var accessor = node.staticElement; |
| 1134 if (accessor == null) { | 1134 if (accessor == null) { |
| 1135 return js.commentExpression( | 1135 return js.commentExpression( |
| 1136 'Unimplemented unknown name', new JS.Identifier(node.name)); | 1136 'Unimplemented unknown name', new JS.Identifier(node.name)); |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 // Get the original declaring element. If we had a property accessor, this | 1139 // Get the original declaring element. If we had a property accessor, this |
| 1140 // indirects back to a (possibly synthetic) field. | 1140 // indirects back to a (possibly synthetic) field. |
| 1141 var element = accessor; | 1141 var element = accessor; |
| 1142 if (element is PropertyAccessorElement) element = accessor.variable; | 1142 if (accessor is PropertyAccessorElement) element = accessor.variable; |
| 1143 | 1143 |
| 1144 _loader.declareBeforeUse(element); | 1144 _loader.declareBeforeUse(element); |
| 1145 | 1145 |
| 1146 var name = element.name; | 1146 var name = element.name; |
| 1147 | 1147 |
| 1148 // type literal | 1148 // type literal |
| 1149 if (element is ClassElement || | 1149 if (element is ClassElement || |
| 1150 element is DynamicElementImpl || | 1150 element is DynamicElementImpl || |
| 1151 element is FunctionTypeAliasElement) { | 1151 element is FunctionTypeAliasElement) { |
| 1152 return _emitTypeName(fillDynamicTypeArgs(element.type, types)); | 1152 return _emitTypeName( |
| 1153 fillDynamicTypeArgs((element as dynamic).type, types)); |
| 1153 } | 1154 } |
| 1154 | 1155 |
| 1155 // library member | 1156 // library member |
| 1156 if (element.enclosingElement is CompilationUnitElement) { | 1157 if (element.enclosingElement is CompilationUnitElement) { |
| 1157 return _maybeQualifiedName( | 1158 return _maybeQualifiedName( |
| 1158 element, _emitMemberName(name, isStatic: true)); | 1159 element, _emitMemberName(name, isStatic: true)); |
| 1159 } | 1160 } |
| 1160 | 1161 |
| 1161 // Unqualified class member. This could mean implicit-this, or implicit | 1162 // Unqualified class member. This could mean implicit-this, or implicit |
| 1162 // call to a static from the same class. | 1163 // call to a static from the same class. |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1746 e.library.name == '_foreign_helper' && | 1747 e.library.name == '_foreign_helper' && |
| 1747 e.name == 'JS') { | 1748 e.name == 'JS') { |
| 1748 // Fix types for JS builtin calls. | 1749 // Fix types for JS builtin calls. |
| 1749 // | 1750 // |
| 1750 // This code was taken from analyzer. It's not super sophisticated: | 1751 // This code was taken from analyzer. It's not super sophisticated: |
| 1751 // only looks for the type name in dart:core, so we just copy it here. | 1752 // only looks for the type name in dart:core, so we just copy it here. |
| 1752 // | 1753 // |
| 1753 // TODO(jmesserly): we'll likely need something that can handle a wider | 1754 // TODO(jmesserly): we'll likely need something that can handle a wider |
| 1754 // variety of types, especially when we get to JS interop. | 1755 // variety of types, especially when we get to JS interop. |
| 1755 var args = expr.argumentList.arguments; | 1756 var args = expr.argumentList.arguments; |
| 1756 if (args.isNotEmpty && args.first is SimpleStringLiteral) { | 1757 var first = args.isNotEmpty ? args.first : null; |
| 1757 var types = args.first.stringValue; | 1758 if (first is SimpleStringLiteral) { |
| 1759 var types = first.stringValue; |
| 1758 if (!types.split('|').contains('Null')) { | 1760 if (!types.split('|').contains('Null')) { |
| 1759 return true; | 1761 return true; |
| 1760 } | 1762 } |
| 1761 } | 1763 } |
| 1762 } | 1764 } |
| 1763 } | 1765 } |
| 1764 return false; | 1766 return false; |
| 1765 } | 1767 } |
| 1766 | 1768 |
| 1767 JS.Expression notNull(Expression expr) { | 1769 JS.Expression notNull(Expression expr) { |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 !_isJSBuiltinType(type) && | 2054 !_isJSBuiltinType(type) && |
| 2053 _isNonNullableExpression(target)) { | 2055 _isNonNullableExpression(target)) { |
| 2054 return false; | 2056 return false; |
| 2055 } | 2057 } |
| 2056 return true; | 2058 return true; |
| 2057 } | 2059 } |
| 2058 | 2060 |
| 2059 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. | 2061 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. |
| 2060 JS.Expression _emitGet(Expression target, SimpleIdentifier memberId) { | 2062 JS.Expression _emitGet(Expression target, SimpleIdentifier memberId) { |
| 2061 var member = memberId.staticElement; | 2063 var member = memberId.staticElement; |
| 2062 if (member is PropertyAccessorElement) member = member.variable; | 2064 if (member is PropertyAccessorElement) { |
| 2065 member = (member as PropertyAccessorElement).variable; |
| 2066 } |
| 2063 bool isStatic = member is ClassMemberElement && member.isStatic; | 2067 bool isStatic = member is ClassMemberElement && member.isStatic; |
| 2064 if (isStatic) { | 2068 if (isStatic) { |
| 2065 _loader.declareBeforeUse(member); | 2069 _loader.declareBeforeUse(member); |
| 2066 } | 2070 } |
| 2067 var name = _emitMemberName(memberId.name, | 2071 var name = _emitMemberName(memberId.name, |
| 2068 type: getStaticType(target), isStatic: isStatic); | 2072 type: getStaticType(target), isStatic: isStatic); |
| 2069 if (rules.isDynamicTarget(target)) { | 2073 if (rules.isDynamicTarget(target)) { |
| 2070 return js.call('dart.$DLOAD(#, #)', [_visit(target), name]); | 2074 return js.call('dart.$DLOAD(#, #)', [_visit(target), name]); |
| 2071 } | 2075 } |
| 2072 | 2076 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 | 2243 |
| 2240 // TODO(jmesserly): this is inconsistent with [visitIsExpression], which | 2244 // TODO(jmesserly): this is inconsistent with [visitIsExpression], which |
| 2241 // has special case for typeof. | 2245 // has special case for typeof. |
| 2242 return new JS.If(js.call('dart.is(#, #)', [ | 2246 return new JS.If(js.call('dart.is(#, #)', [ |
| 2243 _visit(_catchParameter), | 2247 _visit(_catchParameter), |
| 2244 _emitTypeName(clause.exceptionType.type), | 2248 _emitTypeName(clause.exceptionType.type), |
| 2245 ]), then, otherwise); | 2249 ]), then, otherwise); |
| 2246 } | 2250 } |
| 2247 | 2251 |
| 2248 JS.Statement _statement(Iterable stmts) { | 2252 JS.Statement _statement(Iterable stmts) { |
| 2249 var s = stmts is List ? stmts : new List<JS.Statement>.from(stmts); | 2253 List s = stmts is List ? stmts : new List<JS.Statement>.from(stmts); |
| 2250 // TODO(jmesserly): empty block singleton? | 2254 // TODO(jmesserly): empty block singleton? |
| 2251 if (s.length == 0) return new JS.Block([]); | 2255 if (s.length == 0) return new JS.Block([]); |
| 2252 if (s.length == 1) return s[0]; | 2256 if (s.length == 1) return s[0]; |
| 2253 return new JS.Block(s); | 2257 return new JS.Block(s); |
| 2254 } | 2258 } |
| 2255 | 2259 |
| 2256 /// Visits the catch clause body. This skips the exception type guard, if any. | 2260 /// Visits the catch clause body. This skips the exception type guard, if any. |
| 2257 /// That is handled in [_visitCatch]. | 2261 /// That is handled in [_visitCatch]. |
| 2258 @override | 2262 @override |
| 2259 JS.Statement visitCatchClause(CatchClause node) { | 2263 JS.Statement visitCatchClause(CatchClause node) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2646 | 2650 |
| 2647 /// A special kind of element created by the compiler, signifying a temporary | 2651 /// A special kind of element created by the compiler, signifying a temporary |
| 2648 /// variable. These objects use instance equality, and should be shared | 2652 /// variable. These objects use instance equality, and should be shared |
| 2649 /// everywhere in the tree where they are treated as the same variable. | 2653 /// everywhere in the tree where they are treated as the same variable. |
| 2650 class TemporaryVariableElement extends LocalVariableElementImpl { | 2654 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 2651 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 2655 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 2652 | 2656 |
| 2653 int get hashCode => identityHashCode(this); | 2657 int get hashCode => identityHashCode(this); |
| 2654 bool operator ==(Object other) => identical(this, other); | 2658 bool operator ==(Object other) => identical(this, other); |
| 2655 } | 2659 } |
| OLD | NEW |