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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { | 330 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { |
331 var element = node.element; | 331 var element = node.element; |
332 | 332 |
333 // Forward all generative constructors from the base class. | 333 // Forward all generative constructors from the base class. |
334 var body = []; | 334 var body = []; |
335 | 335 |
336 var supertype = element.supertype; | 336 var supertype = element.supertype; |
337 if (!supertype.isObject) { | 337 if (!supertype.isObject) { |
338 for (var ctor in element.constructors) { | 338 for (var ctor in element.constructors) { |
339 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); | 339 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); |
340 var fun = js.call('function() { super.#(...#); }', [ | 340 var fun = js.call('function() { super.#(...arguments); }', |
341 _constructorName(parentCtor), | 341 [_constructorName(parentCtor)]); |
342 new JS.Identifier('arguments', allowRename: false) | |
343 ]); | |
344 body.add(new JS.Method(_constructorName(ctor), fun)); | 342 body.add(new JS.Method(_constructorName(ctor), fun)); |
345 } | 343 } |
346 } | 344 } |
347 | 345 |
348 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( | 346 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( |
349 new JS.Identifier(element.name), _classHeritage(element), body)); | 347 new JS.Identifier(element.name), _classHeritage(element), body)); |
350 | 348 |
351 return _finishClassDef(element.type, classDecl); | 349 return _finishClassDef(element.type, classDecl); |
352 } | 350 } |
353 | 351 |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 // [constructor restrictions] | 836 // [constructor restrictions] |
839 // (https://code.google.com/p/v8/issues/detail?id=3330#c65) | 837 // (https://code.google.com/p/v8/issues/detail?id=3330#c65) |
840 // we cannot currently emit actual ES6 constructors with super calls. | 838 // we cannot currently emit actual ES6 constructors with super calls. |
841 // Instead we use the same trick as named constructors, and do them as | 839 // Instead we use the same trick as named constructors, and do them as |
842 // instance methods that perform initialization. | 840 // instance methods that perform initialization. |
843 // TODO(jmesserly): we'll need to rethink this once the ES6 spec and V8 | 841 // TODO(jmesserly): we'll need to rethink this once the ES6 spec and V8 |
844 // settles. See <https://github.com/dart-lang/dev_compiler/issues/51>. | 842 // settles. See <https://github.com/dart-lang/dev_compiler/issues/51>. |
845 // Performance of this pattern is likely to be bad. | 843 // Performance of this pattern is likely to be bad. |
846 name = _propertyName('constructor'); | 844 name = _propertyName('constructor'); |
847 // Mark the parameter as no-rename. | 845 // Mark the parameter as no-rename. |
848 var args = new JS.Identifier('arguments', allowRename: false); | |
849 body = js.statement('''{ | 846 body = js.statement('''{ |
850 // Get the class name for this instance. | 847 // Get the class name for this instance. |
851 let name = this.constructor.name; | 848 let name = this.constructor.name; |
852 // Call the default constructor. | 849 // Call the default constructor. |
853 let init = this[name]; | |
854 let result = void 0; | 850 let result = void 0; |
855 if (init) result = init.apply(this, #); | 851 if (name in this) result = this[name](...arguments); |
vsm
2015/06/23 19:58:27
Shouldn't this be something like:
if (this.__prot
Jennifer Messerly
2015/06/23 20:08:35
the problem, if it repros, already exists in old c
| |
856 return result === void 0 ? this : result; | 852 return result === void 0 ? this : result; |
857 }''', args); | 853 }'''); |
858 } else { | 854 } else { |
859 body = _emitConstructorBody(node, fields); | 855 body = _emitConstructorBody(node, fields); |
860 } | 856 } |
861 | 857 |
862 // We generate constructors as initializer methods in the class; | 858 // We generate constructors as initializer methods in the class; |
863 // this allows use of `super` for instance methods/properties. | 859 // this allows use of `super` for instance methods/properties. |
864 // It also avoids V8 restrictions on `super` in default constructors. | 860 // It also avoids V8 restrictions on `super` in default constructors. |
865 return new JS.Method(name, new JS.Fun(_visit(node.parameters), body)) | 861 return new JS.Method(name, new JS.Fun(_visit(node.parameters), body)) |
866 ..sourceInformation = node; | 862 ..sourceInformation = node; |
867 } | 863 } |
(...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2802 | 2798 |
2803 /// A special kind of element created by the compiler, signifying a temporary | 2799 /// A special kind of element created by the compiler, signifying a temporary |
2804 /// variable. These objects use instance equality, and should be shared | 2800 /// variable. These objects use instance equality, and should be shared |
2805 /// everywhere in the tree where they are treated as the same variable. | 2801 /// everywhere in the tree where they are treated as the same variable. |
2806 class TemporaryVariableElement extends LocalVariableElementImpl { | 2802 class TemporaryVariableElement extends LocalVariableElementImpl { |
2807 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 2803 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
2808 | 2804 |
2809 int get hashCode => identityHashCode(this); | 2805 int get hashCode => identityHashCode(this); |
2810 bool operator ==(Object other) => identical(this, other); | 2806 bool operator ==(Object other) => identical(this, other); |
2811 } | 2807 } |
OLD | NEW |