Chromium Code Reviews| 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 var supertype = element.supertype; | 368 var supertype = element.supertype; |
| 369 if (!supertype.isObject) { | 369 if (!supertype.isObject) { |
| 370 for (var ctor in element.constructors) { | 370 for (var ctor in element.constructors) { |
| 371 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); | 371 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); |
| 372 var fun = js.call('function() { super.#(...arguments); }', | 372 var fun = js.call('function() { super.#(...arguments); }', |
| 373 [_constructorName(parentCtor)]) as JS.Fun; | 373 [_constructorName(parentCtor)]) as JS.Fun; |
| 374 body.add(new JS.Method(_constructorName(ctor), fun)); | 374 body.add(new JS.Method(_constructorName(ctor), fun)); |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( | 378 var classExpr = new JS.ClassExpression( |
| 379 new JS.Identifier(element.name), _classHeritage(element), body)); | 379 new JS.Identifier(element.name), _classHeritage(element), body); |
| 380 | 380 |
| 381 return _finishClassDef(element.type, classDecl); | 381 return _finishClassDef(element.type, _emitClassDeclaration(classExpr)); |
|
Jennifer Messerly
2016/02/01 23:59:55
The same fix is likely needed for ClassTypeAlias
ochafik
2016/02/03 19:41:33
Done.
| |
| 382 } | 382 } |
| 383 | 383 |
| 384 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { | 384 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { |
| 385 var jsTypeName = | 385 var jsTypeName = |
| 386 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); | 386 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
| 387 | 387 |
| 388 if (jsTypeName != null && jsTypeName != dartClassName) { | 388 if (jsTypeName != null && jsTypeName != dartClassName) { |
| 389 // We export the JS type as if it was a Dart type. For example this allows | 389 // We export the JS type as if it was a Dart type. For example this allows |
| 390 // `dom.InputElement` to actually be HTMLInputElement. | 390 // `dom.InputElement` to actually be HTMLInputElement. |
| 391 // TODO(jmesserly): if we had the JS name on the Element, we could just | 391 // TODO(jmesserly): if we had the JS name on the Element, we could just |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 JS.Expression _instantiateAnnotation(Annotation node) { | 662 JS.Expression _instantiateAnnotation(Annotation node) { |
| 663 var element = node.element; | 663 var element = node.element; |
| 664 if (element is ConstructorElement) { | 664 if (element is ConstructorElement) { |
| 665 return _emitInstanceCreationExpression(element, element.returnType, | 665 return _emitInstanceCreationExpression(element, element.returnType, |
| 666 node.constructorName, node.arguments, true); | 666 node.constructorName, node.arguments, true); |
| 667 } else { | 667 } else { |
| 668 return _visit(node.name); | 668 return _visit(node.name); |
| 669 } | 669 } |
| 670 } | 670 } |
| 671 | 671 |
| 672 _isQualifiedPath(JS.Expression node) => | |
| 673 node is JS.Identifier || | |
| 674 node is JS.PropertyAccess && | |
| 675 _isQualifiedPath(node.receiver) && | |
| 676 node.selector is JS.LiteralString; | |
| 677 | |
| 678 JS.Statement _emitClassDeclaration(JS.ClassExpression cls) { | |
|
Jennifer Messerly
2016/02/01 23:59:55
from the naming convention, I would probably expec
ochafik
2016/02/03 19:41:33
Done.
| |
| 679 var body = <JS.Statement>[]; | |
|
Jennifer Messerly
2016/02/01 23:59:55
this can go inside the if:
if (...) {
return ne
ochafik
2016/02/03 19:41:33
Done.
| |
| 680 if (options.closure && | |
| 681 cls.heritage != null && !_isQualifiedPath(cls.heritage)) { | |
| 682 // Workaround for Closure: super classes must be qualified paths. | |
|
Jennifer Messerly
2016/02/01 23:59:55
After the method rename, this would be good as a d
ochafik
2016/02/03 19:41:33
Done.
| |
| 683 var superVar = new JS.Identifier(cls.name.name + r'$super'); | |
|
Jennifer Messerly
2016/02/01 23:59:55
This should be a temp. Use `new JS.TemporaryId`. T
ochafik
2016/02/03 19:41:33
Done.
| |
| 684 body.add(js.statement('const # = #;', [superVar, cls.heritage])); | |
| 685 cls = new JS.ClassExpression(cls.name, superVar, cls.methods); | |
| 686 } | |
| 687 body.add(new JS.ClassDeclaration(cls)); | |
| 688 return _statement(body); | |
| 689 } | |
| 690 | |
| 672 /// Emit class members that need to come after the class declaration, such | 691 /// Emit class members that need to come after the class declaration, such |
| 673 /// as static fields. See [_emitClassMethods] for things that are emitted | 692 /// as static fields. See [_emitClassMethods] for things that are emitted |
| 674 /// inside the ES6 `class { ... }` node. | 693 /// inside the ES6 `class { ... }` node. |
| 675 JS.Statement _finishClassMembers( | 694 JS.Statement _finishClassMembers( |
| 676 ClassElement classElem, | 695 ClassElement classElem, |
| 677 JS.ClassExpression cls, | 696 JS.ClassExpression cls, |
| 678 List<ConstructorDeclaration> ctors, | 697 List<ConstructorDeclaration> ctors, |
| 679 List<FieldDeclaration> fields, | 698 List<FieldDeclaration> fields, |
| 680 List<MethodDeclaration> methods, | 699 List<MethodDeclaration> methods, |
| 681 List<Annotation> metadata, | 700 List<Annotation> metadata, |
| 682 String jsPeerName) { | 701 String jsPeerName) { |
| 683 var name = classElem.name; | 702 var name = classElem.name; |
| 684 var body = <JS.Statement>[]; | 703 var body = <JS.Statement>[]; |
| 685 | 704 |
| 686 if (_extensionTypes.contains(classElem)) { | 705 if (_extensionTypes.contains(classElem)) { |
| 687 var dartxNames = <JS.Expression>[]; | 706 var dartxNames = <JS.Expression>[]; |
| 688 for (var m in methods) { | 707 for (var m in methods) { |
| 689 if (!m.isAbstract && !m.isStatic && m.element.isPublic) { | 708 if (!m.isAbstract && !m.isStatic && m.element.isPublic) { |
| 690 dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); | 709 dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); |
| 691 } | 710 } |
| 692 } | 711 } |
| 693 if (dartxNames.isNotEmpty) { | 712 if (dartxNames.isNotEmpty) { |
| 694 body.add(js.statement('dart.defineExtensionNames(#)', | 713 body.add(js.statement('dart.defineExtensionNames(#)', |
| 695 [new JS.ArrayInitializer(dartxNames, multiline: true)])); | 714 [new JS.ArrayInitializer(dartxNames, multiline: true)])); |
| 696 } | 715 } |
| 697 } | 716 } |
| 698 | 717 |
| 699 body.add(new JS.ClassDeclaration(cls)); | 718 body.add(_emitClassDeclaration(cls)); |
| 700 | 719 |
| 701 // TODO(jmesserly): we should really just extend native Array. | 720 // TODO(jmesserly): we should really just extend native Array. |
| 702 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { | 721 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { |
| 703 body.add(js.statement('dart.setBaseClass(#, dart.global.#);', | 722 body.add(js.statement('dart.setBaseClass(#, dart.global.#);', |
| 704 [classElem.name, _propertyName(jsPeerName)])); | 723 [classElem.name, _propertyName(jsPeerName)])); |
| 705 } | 724 } |
| 706 | 725 |
| 707 // Deferred Superclass | 726 // Deferred Superclass |
| 708 if (_hasDeferredSupertype.contains(classElem)) { | 727 if (_hasDeferredSupertype.contains(classElem)) { |
| 709 body.add(js.statement('#.prototype.__proto__ = #.prototype;', | 728 body.add(js.statement('#.prototype.__proto__ = #.prototype;', |
| (...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3592 | 3611 |
| 3593 /// A special kind of element created by the compiler, signifying a temporary | 3612 /// A special kind of element created by the compiler, signifying a temporary |
| 3594 /// variable. These objects use instance equality, and should be shared | 3613 /// variable. These objects use instance equality, and should be shared |
| 3595 /// everywhere in the tree where they are treated as the same variable. | 3614 /// everywhere in the tree where they are treated as the same variable. |
| 3596 class TemporaryVariableElement extends LocalVariableElementImpl { | 3615 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3597 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3616 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3598 | 3617 |
| 3599 int get hashCode => identityHashCode(this); | 3618 int get hashCode => identityHashCode(this); |
| 3600 bool operator ==(Object other) => identical(this, other); | 3619 bool operator ==(Object other) => identical(this, other); |
| 3601 } | 3620 } |
| OLD | NEW |