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 |