| 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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 body.add(_overrideField(field)); | 704 body.add(_overrideField(field)); |
| 705 } | 705 } |
| 706 } | 706 } |
| 707 } | 707 } |
| 708 | 708 |
| 709 // Static fields | 709 // Static fields |
| 710 var lazyStatics = <VariableDeclaration>[]; | 710 var lazyStatics = <VariableDeclaration>[]; |
| 711 for (FieldDeclaration member in staticFields) { | 711 for (FieldDeclaration member in staticFields) { |
| 712 for (VariableDeclaration field in member.fields.variables) { | 712 for (VariableDeclaration field in member.fields.variables) { |
| 713 var fieldName = field.name.name; | 713 var fieldName = field.name.name; |
| 714 if ((field.isConst || _isFieldInitConstant(field)) && | 714 // TODO(vsm): This is a workaround until this is fixed: |
| 715 // https://github.com/dart-lang/dev_compiler/issues/131 |
| 716 if ((/*field.isConst || */ _isFieldInitConstant(field)) && |
| 715 !JS.invalidStaticFieldName(fieldName)) { | 717 !JS.invalidStaticFieldName(fieldName)) { |
| 716 var init = _visit(field.initializer); | 718 var init = _visit(field.initializer); |
| 717 if (init == null) init = new JS.LiteralNull(); | 719 if (init == null) init = new JS.LiteralNull(); |
| 720 fieldName = _emitMemberName(fieldName, isStatic: true); |
| 718 body.add(js.statement('#.# = #;', [name, fieldName, init])); | 721 body.add(js.statement('#.# = #;', [name, fieldName, init])); |
| 719 } else { | 722 } else { |
| 720 lazyStatics.add(field); | 723 lazyStatics.add(field); |
| 721 } | 724 } |
| 722 } | 725 } |
| 723 } | 726 } |
| 724 var lazy = _emitLazyFields(new JS.Identifier(name), lazyStatics); | 727 var lazy = _emitLazyFields(new JS.Identifier(name), lazyStatics); |
| 725 if (lazy != null) body.add(lazy); | 728 if (lazy != null) body.add(lazy); |
| 726 return _statement(body); | 729 return _statement(body); |
| 727 } | 730 } |
| (...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 return js.call( | 2052 return js.call( |
| 2050 'dart.$dynamicHelper(#, #)', [_visit(target), _visitList(args)]); | 2053 'dart.$dynamicHelper(#, #)', [_visit(target), _visitList(args)]); |
| 2051 } | 2054 } |
| 2052 return js.call('dart.$DSEND(#, #, #)', [ | 2055 return js.call('dart.$DSEND(#, #, #)', [ |
| 2053 _visit(target), | 2056 _visit(target), |
| 2054 memberName, | 2057 memberName, |
| 2055 _visitList(args) | 2058 _visitList(args) |
| 2056 ]); | 2059 ]); |
| 2057 } | 2060 } |
| 2058 | 2061 |
| 2059 if (_isJSBuiltinType(type)) { | |
| 2060 // static call pattern for builtins. | |
| 2061 return js.call('#.#(#, #)', [ | |
| 2062 _emitTypeName(type), | |
| 2063 memberName, | |
| 2064 _visit(target), | |
| 2065 _visitList(args) | |
| 2066 ]); | |
| 2067 } | |
| 2068 // Generic dispatch to a statically known method. | 2062 // Generic dispatch to a statically known method. |
| 2069 return js.call('#.#(#)', [_visit(target), memberName, _visitList(args)]); | 2063 return js.call('#.#(#)', [_visit(target), memberName, _visitList(args)]); |
| 2070 } | 2064 } |
| 2071 | 2065 |
| 2072 @override | 2066 @override |
| 2073 visitIndexExpression(IndexExpression node) { | 2067 visitIndexExpression(IndexExpression node) { |
| 2074 return _emitSend(_getTarget(node), '[]', [node.index]); | 2068 return _emitSend(_getTarget(node), '[]', [node.index]); |
| 2075 } | 2069 } |
| 2076 | 2070 |
| 2077 /// Gets the target of a [PropertyAccess] or [IndexExpression]. | 2071 /// Gets the target of a [PropertyAccess] or [IndexExpression]. |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2374 @override | 2368 @override |
| 2375 visitNode(AstNode node) { | 2369 visitNode(AstNode node) { |
| 2376 // TODO(jmesserly): verify this is unreachable. | 2370 // TODO(jmesserly): verify this is unreachable. |
| 2377 throw 'Unimplemented ${node.runtimeType}: $node'; | 2371 throw 'Unimplemented ${node.runtimeType}: $node'; |
| 2378 } | 2372 } |
| 2379 | 2373 |
| 2380 // TODO(jmesserly): this is used to determine if the field initialization is | 2374 // TODO(jmesserly): this is used to determine if the field initialization is |
| 2381 // side effect free. We should make the check more general, as things like | 2375 // side effect free. We should make the check more general, as things like |
| 2382 // list/map literals/regexp are also side effect free and fairly common | 2376 // list/map literals/regexp are also side effect free and fairly common |
| 2383 // to use as field initializers. | 2377 // to use as field initializers. |
| 2384 bool _isFieldInitConstant(VariableDeclaration field) => | 2378 // TODO(vsm): Restore once this is fixed: |
| 2385 field.initializer == null || _computeConstant(field).isValid; | 2379 // https://github.com/dart-lang/dev_compiler/issues/131 |
| 2380 bool _isFieldInitConstant(VariableDeclaration field) { |
| 2381 var initializer = field.initializer; |
| 2382 if (initializer == null) return true; |
| 2383 if (field.isConst || _computeConstant(field).isValid) { |
| 2384 return initializer is Literal && initializer is! TypedLiteral; |
| 2385 } |
| 2386 return false; |
| 2387 } |
| 2386 | 2388 |
| 2387 EvaluationResult _computeConstant(VariableDeclaration field) { | 2389 EvaluationResult _computeConstant(VariableDeclaration field) { |
| 2388 // If the constant is already computed by ConstantEvaluator, just return it. | 2390 // If the constant is already computed by ConstantEvaluator, just return it. |
| 2389 VariableElementImpl element = field.element; | 2391 VariableElementImpl element = field.element; |
| 2390 var result = element.evaluationResult; | 2392 var result = element.evaluationResult; |
| 2391 if (result != null) return result; | 2393 if (result != null) return result; |
| 2392 | 2394 |
| 2393 // ConstantEvaluator will not compute constants for non-const fields | 2395 // ConstantEvaluator will not compute constants for non-const fields |
| 2394 // at least for cases like `int x = 0;`, so run ConstantVisitor for those. | 2396 // at least for cases like `int x = 0;`, so run ConstantVisitor for those. |
| 2395 // TODO(jmesserly): ideally we'd only do this if we're sure it was skipped | 2397 // TODO(jmesserly): ideally we'd only do this if we're sure it was skipped |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 // TODO(jmesserly): validate the library. See issue #135. | 2614 // TODO(jmesserly): validate the library. See issue #135. |
| 2613 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; | 2615 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; |
| 2614 | 2616 |
| 2615 bool _isJsPeerInterface(DartObjectImpl value) => | 2617 bool _isJsPeerInterface(DartObjectImpl value) => |
| 2616 value.type.name == 'JsPeerInterface'; | 2618 value.type.name == 'JsPeerInterface'; |
| 2617 | 2619 |
| 2618 // TODO(jacobr): we would like to do something like the following | 2620 // TODO(jacobr): we would like to do something like the following |
| 2619 // but we don't have summary support yet. | 2621 // but we don't have summary support yet. |
| 2620 // bool _supportJsExtensionMethod(AnnotatedNode node) => | 2622 // bool _supportJsExtensionMethod(AnnotatedNode node) => |
| 2621 // _getAnnotation(node, "SupportJsExtensionMethod") != null; | 2623 // _getAnnotation(node, "SupportJsExtensionMethod") != null; |
| OLD | NEW |