Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1638533004: Create local alias for super class in --closure mode (issue #312) (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: fix test Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runtime/dart/_runtime.js ('k') | test/codegen/expect/closure.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
6 6
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
8 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 8 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
9 import 'package:analyzer/src/generated/constant.dart'; 9 import 'package:analyzer/src/generated/constant.dart';
10 import 'package:analyzer/src/generated/element.dart'; 10 import 'package:analyzer/src/generated/element.dart';
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 var supertype = element.supertype; 372 var supertype = element.supertype;
373 if (!supertype.isObject) { 373 if (!supertype.isObject) {
374 for (var ctor in element.constructors) { 374 for (var ctor in element.constructors) {
375 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); 375 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library);
376 var fun = js.call('function() { super.#(...arguments); }', 376 var fun = js.call('function() { super.#(...arguments); }',
377 [_constructorName(parentCtor)]) as JS.Fun; 377 [_constructorName(parentCtor)]) as JS.Fun;
378 body.add(new JS.Method(_constructorName(ctor), fun)); 378 body.add(new JS.Method(_constructorName(ctor), fun));
379 } 379 }
380 } 380 }
381 381
382 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( 382 var classExpr = new JS.ClassExpression(
383 new JS.Identifier(element.name), _classHeritage(element), body)); 383 new JS.Identifier(element.name), _classHeritage(element), body);
384 384
385 return _finishClassDef(element.type, classDecl); 385 return _finishClassDef(
386 element.type, _emitClassHeritageWorkaround(classExpr));
386 } 387 }
387 388
388 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { 389 JS.Statement _emitJsType(String dartClassName, DartObject jsName) {
389 var jsTypeName = 390 var jsTypeName =
390 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); 391 getConstantField(jsName, 'name', types.stringType)?.toStringValue();
391 392
392 if (jsTypeName != null && jsTypeName != dartClassName) { 393 if (jsTypeName != null && jsTypeName != dartClassName) {
393 // We export the JS type as if it was a Dart type. For example this allows 394 // We export the JS type as if it was a Dart type. For example this allows
394 // `dom.InputElement` to actually be HTMLInputElement. 395 // `dom.InputElement` to actually be HTMLInputElement.
395 // TODO(jmesserly): if we had the JS name on the Element, we could just 396 // TODO(jmesserly): if we had the JS name on the Element, we could just
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 JS.Expression _instantiateAnnotation(Annotation node) { 668 JS.Expression _instantiateAnnotation(Annotation node) {
668 var element = node.element; 669 var element = node.element;
669 if (element is ConstructorElement) { 670 if (element is ConstructorElement) {
670 return _emitInstanceCreationExpression(element, element.returnType, 671 return _emitInstanceCreationExpression(element, element.returnType,
671 node.constructorName, node.arguments, true); 672 node.constructorName, node.arguments, true);
672 } else { 673 } else {
673 return _visit(node.name); 674 return _visit(node.name);
674 } 675 }
675 } 676 }
676 677
678 _isQualifiedPath(JS.Expression node) =>
679 node is JS.Identifier ||
680 node is JS.PropertyAccess &&
681 _isQualifiedPath(node.receiver) &&
682 node.selector is JS.LiteralString;
683
684 /// Workaround for Closure: super classes must be qualified paths.
685 JS.Statement _emitClassHeritageWorkaround(JS.ClassExpression cls) {
686 if (options.closure &&
687 cls.heritage != null &&
688 !_isQualifiedPath(cls.heritage)) {
689 var superVar = new JS.TemporaryId(cls.name.name + r'$super');
690 return _statement([
691 js.statement('const # = #;', [superVar, cls.heritage]),
692 new JS.ClassDeclaration(
693 new JS.ClassExpression(cls.name, superVar, cls.methods))
694 ]);
695 }
696 return new JS.ClassDeclaration(cls);
697 }
698
677 /// Emit class members that need to come after the class declaration, such 699 /// Emit class members that need to come after the class declaration, such
678 /// as static fields. See [_emitClassMethods] for things that are emitted 700 /// as static fields. See [_emitClassMethods] for things that are emitted
679 /// inside the ES6 `class { ... }` node. 701 /// inside the ES6 `class { ... }` node.
680 JS.Statement _finishClassMembers( 702 JS.Statement _finishClassMembers(
681 ClassElement classElem, 703 ClassElement classElem,
682 JS.ClassExpression cls, 704 JS.ClassExpression cls,
683 List<ConstructorDeclaration> ctors, 705 List<ConstructorDeclaration> ctors,
684 List<FieldDeclaration> fields, 706 List<FieldDeclaration> fields,
685 List<FieldDeclaration> staticFields, 707 List<FieldDeclaration> staticFields,
686 List<MethodDeclaration> methods, 708 List<MethodDeclaration> methods,
687 List<Annotation> metadata, 709 List<Annotation> metadata,
688 String jsPeerName) { 710 String jsPeerName) {
689 var name = classElem.name; 711 var name = classElem.name;
690 var body = <JS.Statement>[]; 712 var body = <JS.Statement>[];
691 713
692 if (_extensionTypes.contains(classElem)) { 714 if (_extensionTypes.contains(classElem)) {
693 var dartxNames = <JS.Expression>[]; 715 var dartxNames = <JS.Expression>[];
694 for (var m in methods) { 716 for (var m in methods) {
695 if (!m.isAbstract && !m.isStatic && m.element.isPublic) { 717 if (!m.isAbstract && !m.isStatic && m.element.isPublic) {
696 dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); 718 dartxNames.add(_elementMemberName(m.element, allowExtensions: false));
697 } 719 }
698 } 720 }
699 if (dartxNames.isNotEmpty) { 721 if (dartxNames.isNotEmpty) {
700 body.add(js.statement('dart.defineExtensionNames(#)', 722 body.add(js.statement('dart.defineExtensionNames(#)',
701 [new JS.ArrayInitializer(dartxNames, multiline: true)])); 723 [new JS.ArrayInitializer(dartxNames, multiline: true)]));
702 } 724 }
703 } 725 }
704 726
705 body.add(new JS.ClassDeclaration(cls)); 727 body.add(_emitClassHeritageWorkaround(cls));
706 728
707 // TODO(jmesserly): we should really just extend native Array. 729 // TODO(jmesserly): we should really just extend native Array.
708 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { 730 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) {
709 body.add(js.statement('dart.setBaseClass(#, dart.global.#);', 731 body.add(js.statement('dart.setBaseClass(#, dart.global.#);',
710 [classElem.name, _propertyName(jsPeerName)])); 732 [classElem.name, _propertyName(jsPeerName)]));
711 } 733 }
712 734
713 // Deferred Superclass 735 // Deferred Superclass
714 if (_hasDeferredSupertype.contains(classElem)) { 736 if (_hasDeferredSupertype.contains(classElem)) {
715 body.add(js.statement('#.prototype.__proto__ = #.prototype;', 737 body.add(js.statement('#.prototype.__proto__ = #.prototype;',
(...skipping 2873 matching lines...) Expand 10 before | Expand all | Expand 10 after
3589 3611
3590 /// 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
3591 /// variable. These objects use instance equality, and should be shared 3613 /// variable. These objects use instance equality, and should be shared
3592 /// 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.
3593 class TemporaryVariableElement extends LocalVariableElementImpl { 3615 class TemporaryVariableElement extends LocalVariableElementImpl {
3594 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3616 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3595 3617
3596 int get hashCode => identityHashCode(this); 3618 int get hashCode => identityHashCode(this);
3597 bool operator ==(Object other) => identical(this, other); 3619 bool operator ==(Object other) => identical(this, other);
3598 } 3620 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/_runtime.js ('k') | test/codegen/expect/closure.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698