| 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 ddc.src.codegen.js_codegen; | 5 library ddc.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:io' show Directory, File; | 7 import 'dart:io' show Directory, File; |
| 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 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 | 317 |
| 318 var body = _initializeFields(fields); | 318 var body = _initializeFields(fields); |
| 319 var superCall = _superConstructorCall(node); | 319 var superCall = _superConstructorCall(node); |
| 320 if (superCall != null) body = [[body, superCall]]; | 320 if (superCall != null) body = [[body, superCall]]; |
| 321 return new JS.Method( | 321 return new JS.Method( |
| 322 new JS.PropertyName(name), js.call('function() { #; }', body)); | 322 new JS.PropertyName(name), js.call('function() { #; }', body)); |
| 323 } | 323 } |
| 324 | 324 |
| 325 JS.Method _emitConstructor(ConstructorDeclaration node, String className, | 325 JS.Method _emitConstructor(ConstructorDeclaration node, String className, |
| 326 List<FieldDeclaration> fields) { | 326 List<FieldDeclaration> fields) { |
| 327 if (node.externalKeyword != null) return null; | 327 if (_externalOrNative(node)) return null; |
| 328 | 328 |
| 329 var name = _constructorName(className, node.name); | 329 var name = _constructorName(className, node.name); |
| 330 | 330 |
| 331 // We generate constructors as initializer methods in the class; | 331 // We generate constructors as initializer methods in the class; |
| 332 // this allows use of `super` for instance methods/properties. | 332 // this allows use of `super` for instance methods/properties. |
| 333 // It also avoids V8 restrictions on `super` in default constructors. | 333 // It also avoids V8 restrictions on `super` in default constructors. |
| 334 return new JS.Method(new JS.PropertyName(name), new JS.Fun( | 334 return new JS.Method(new JS.PropertyName(name), new JS.Fun( |
| 335 node.parameters.accept(this), _emitConstructorBody(node, fields))); | 335 node.parameters.accept(this), _emitConstructorBody(node, fields))); |
| 336 } | 336 } |
| 337 | 337 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 JS.Expression _defaultParamValue(FormalParameter param) { | 533 JS.Expression _defaultParamValue(FormalParameter param) { |
| 534 if (param is DefaultFormalParameter && param.defaultValue != null) { | 534 if (param is DefaultFormalParameter && param.defaultValue != null) { |
| 535 return param.defaultValue.accept(this); | 535 return param.defaultValue.accept(this); |
| 536 } else { | 536 } else { |
| 537 return new JS.LiteralNull(); | 537 return new JS.LiteralNull(); |
| 538 } | 538 } |
| 539 } | 539 } |
| 540 | 540 |
| 541 @override | 541 @override |
| 542 JS.Method visitMethodDeclaration(MethodDeclaration node) { | 542 JS.Method visitMethodDeclaration(MethodDeclaration node) { |
| 543 if (node.isAbstract || node.externalKeyword != null) return null; | 543 if (node.isAbstract || _externalOrNative(node)) { |
| 544 return null; |
| 545 } |
| 544 | 546 |
| 545 var params = _visit(node.parameters); | 547 var params = _visit(node.parameters); |
| 546 if (params == null) params = []; | 548 if (params == null) params = []; |
| 547 | 549 |
| 548 return new JS.Method(new JS.PropertyName(_jsMethodName(node.name.name)), | 550 return new JS.Method(new JS.PropertyName(_jsMethodName(node.name.name)), |
| 549 new JS.Fun(params, node.body.accept(this)), | 551 new JS.Fun(params, node.body.accept(this)), |
| 550 isGetter: node.isGetter, | 552 isGetter: node.isGetter, |
| 551 isSetter: node.isSetter, | 553 isSetter: node.isSetter, |
| 552 isStatic: node.isStatic); | 554 isStatic: node.isStatic); |
| 553 } | 555 } |
| 554 | 556 |
| 555 @override | 557 @override |
| 556 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { | 558 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { |
| 557 assert(node.parent is CompilationUnit); | 559 assert(node.parent is CompilationUnit); |
| 558 | 560 |
| 559 if (node.externalKeyword != null) return null; | 561 if (_externalOrNative(node)) return null; |
| 560 | 562 |
| 561 if (node.isGetter || node.isSetter) { | 563 if (node.isGetter || node.isSetter) { |
| 562 // Add these later so we can use getter/setter syntax. | 564 // Add these later so we can use getter/setter syntax. |
| 563 _properties.add(node); | 565 _properties.add(node); |
| 564 return null; | 566 return null; |
| 565 } | 567 } |
| 566 | 568 |
| 567 var body = <JS.Statement>[]; | 569 var body = <JS.Statement>[]; |
| 568 _flushLibraryProperties(body); | 570 _flushLibraryProperties(body); |
| 569 | 571 |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 /// x['+'](y) | 1595 /// x['+'](y) |
| 1594 /// | 1596 /// |
| 1595 /// Equality is a bit special, it is generated via the Dart `equals` runtime | 1597 /// Equality is a bit special, it is generated via the Dart `equals` runtime |
| 1596 /// helper, that checks for null. The user defined method is called '=='. | 1598 /// helper, that checks for null. The user defined method is called '=='. |
| 1597 String _jsMethodName(String name) { | 1599 String _jsMethodName(String name) { |
| 1598 if (name == '[]') return 'get'; | 1600 if (name == '[]') return 'get'; |
| 1599 if (name == '[]=') return 'set'; | 1601 if (name == '[]=') return 'set'; |
| 1600 return name; | 1602 return name; |
| 1601 } | 1603 } |
| 1602 | 1604 |
| 1605 bool _externalOrNative(node) => |
| 1606 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; |
| 1607 |
| 1608 FunctionBody _functionBody(node) => |
| 1609 node is FunctionDeclaration ? node.functionExpression.body : node.body; |
| 1610 |
| 1603 String _maybeBindThis(node) { | 1611 String _maybeBindThis(node) { |
| 1604 if (currentClass == null) return ''; | 1612 if (currentClass == null) return ''; |
| 1605 var visitor = _BindThisVisitor._instance; | 1613 var visitor = _BindThisVisitor._instance; |
| 1606 visitor._bindThis = false; | 1614 visitor._bindThis = false; |
| 1607 node.accept(visitor); | 1615 node.accept(visitor); |
| 1608 return visitor._bindThis ? '.bind(this)' : ''; | 1616 return visitor._bindThis ? '.bind(this)' : ''; |
| 1609 } | 1617 } |
| 1610 | 1618 |
| 1611 static bool _needsImplicitThis(Element e) => | 1619 static bool _needsImplicitThis(Element e) => |
| 1612 e is PropertyAccessorElement && !e.variable.isStatic || | 1620 e is PropertyAccessorElement && !e.variable.isStatic || |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1705 /// Choose a canonical name from the library element. | 1713 /// Choose a canonical name from the library element. |
| 1706 /// This never uses the library's name (the identifier in the `library` | 1714 /// This never uses the library's name (the identifier in the `library` |
| 1707 /// declaration) as it doesn't have any meaningful rules enforced. | 1715 /// declaration) as it doesn't have any meaningful rules enforced. |
| 1708 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library); | 1716 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library); |
| 1709 | 1717 |
| 1710 /// Path to file that will be generated for [info]. | 1718 /// Path to file that will be generated for [info]. |
| 1711 // TODO(jmesserly): library directory should be relative to its package | 1719 // TODO(jmesserly): library directory should be relative to its package |
| 1712 // root. For example, "package:dev_compiler/src/codegen/js_codegen.dart" would b
e: | 1720 // root. For example, "package:dev_compiler/src/codegen/js_codegen.dart" would b
e: |
| 1713 // "ddc/src/codegen/js_codegen.js" under the output directory. | 1721 // "ddc/src/codegen/js_codegen.js" under the output directory. |
| 1714 String jsOutputPath(LibraryInfo info) => '${info.name}/${info.name}.js'; | 1722 String jsOutputPath(LibraryInfo info) => '${info.name}/${info.name}.js'; |
| OLD | NEW |