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

Side by Side Diff: lib/src/compiler/code_generator.dart

Issue 1918033002: Remove virtualField helper, just emit getters/setters in codegen. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 8 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_sdk.js ('k') | test/codegen/expect/fieldtest.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 HashMap, HashSet; 5 import 'dart:collection' show HashMap, HashSet;
6 6
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
8 import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator; 8 import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator;
9 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; 9 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
10 import 'package:analyzer/dart/element/element.dart'; 10 import 'package:analyzer/dart/element/element.dart';
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 Expression _cascadeTarget; 74 Expression _cascadeTarget;
75 75
76 /// The variable for the current catch clause 76 /// The variable for the current catch clause
77 SimpleIdentifier _catchParameter; 77 SimpleIdentifier _catchParameter;
78 78
79 /// In an async* function, this represents the stream controller parameter. 79 /// In an async* function, this represents the stream controller parameter.
80 JS.TemporaryId _asyncStarController; 80 JS.TemporaryId _asyncStarController;
81 81
82 final _privateNames = 82 final _privateNames =
83 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); 83 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>();
84 final _virtualFields = new HashMap<VariableDeclaration, JS.TemporaryId>();
Jennifer Messerly 2016/04/25 22:47:04 Generally we don't use AST nodes as hash keys. Sho
Harry Terkelsen 2016/04/26 18:29:27 Done.
85 final _virtualFieldSymbols = new HashMap<ClassElement, List<JS.Statement>>();
Jennifer Messerly 2016/04/25 22:47:04 do we need this map? could we simply keep a List<J
Harry Terkelsen 2016/04/26 18:29:27 Done.
84 final _initializingFormalTemps = 86 final _initializingFormalTemps =
85 new HashMap<ParameterElement, JS.TemporaryId>(); 87 new HashMap<ParameterElement, JS.TemporaryId>();
86 88
87 final _dartxVar = new JS.Identifier('dartx'); 89 final _dartxVar = new JS.Identifier('dartx');
88 final _runtimeLibVar = new JS.Identifier('dart'); 90 final _runtimeLibVar = new JS.Identifier('dart');
89 final namedArgumentTemp = new JS.TemporaryId('opts'); 91 final namedArgumentTemp = new JS.TemporaryId('opts');
90 92
91 final _hasDeferredSupertype = new HashSet<ClassElement>(); 93 final _hasDeferredSupertype = new HashSet<ClassElement>();
92 94
93 /// The type provider from the current Analysis [context]. 95 /// The type provider from the current Analysis [context].
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 for (var member in node.members) { 526 for (var member in node.members) {
525 if (member is ConstructorDeclaration) { 527 if (member is ConstructorDeclaration) {
526 ctors.add(member); 528 ctors.add(member);
527 } else if (member is FieldDeclaration) { 529 } else if (member is FieldDeclaration) {
528 (member.isStatic ? staticFields : fields).add(member); 530 (member.isStatic ? staticFields : fields).add(member);
529 } else if (member is MethodDeclaration) { 531 } else if (member is MethodDeclaration) {
530 methods.add(member); 532 methods.add(member);
531 } 533 }
532 } 534 }
533 535
536 JS.Expression className;
537 if (classElem.typeParameters.isNotEmpty) {
538 className = new JS.Identifier(classElem.name);
Jennifer Messerly 2016/04/25 22:47:04 there was a comment below: "// Generic classes wil
Harry Terkelsen 2016/04/26 18:29:27 Done.
539 } else {
540 className = _emitTopLevelName(classElem);
541 }
542
534 var allFields = new List.from(fields)..addAll(staticFields); 543 var allFields = new List.from(fields)..addAll(staticFields);
535 var classExpr = _emitClassExpression( 544 var classExpr = _emitClassExpression(
536 classElem, _emitClassMethods(node, ctors, fields), 545 classElem, _emitClassMethods(node, ctors, fields, className, classElem),
537 fields: allFields); 546 fields: allFields);
538 547
539 var body = <JS.Statement>[]; 548 var body = <JS.Statement>[];
540 var extensions = _extensionsToImplement(classElem); 549 var extensions = _extensionsToImplement(classElem);
541 _initExtensionSymbols(classElem, methods, fields, body); 550 _initExtensionSymbols(classElem, methods, fields, body);
542 551
543 // Emit the class, e.g. `core.Object = class Object { ... }` 552 // Emit the class, e.g. `core.Object = class Object { ... }`
544 JS.Expression className = _defineClass(classElem, classExpr, body); 553 _defineClass(classElem, className, classExpr, body);
545 554
546 // Emit things that come after the ES6 `class ... { ... }`. 555 // Emit things that come after the ES6 `class ... { ... }`.
547 _setBaseClass(classElem, className, body); 556 _setBaseClass(classElem, className, body);
548 _defineNamedConstructors(ctors, body, className); 557 _defineNamedConstructors(ctors, body, className);
549 _emitVirtualFields(classElem, fields, className, body); 558 _emitVirtualFieldSymbols(classElem, body);
550 _emitClassSignature(methods, classElem, ctors, extensions, className, body); 559 _emitClassSignature(methods, classElem, ctors, extensions, className, body);
551 _defineExtensionMembers(extensions, className, body); 560 _defineExtensionMembers(extensions, className, body);
552 _emitClassMetadata(node.metadata, className, body); 561 _emitClassMetadata(node.metadata, className, body);
553 562
554 JS.Statement classDef = _statement(body); 563 JS.Statement classDef = _statement(body);
555 var typeFormals = classElem.typeParameters; 564 var typeFormals = classElem.typeParameters;
556 if (typeFormals.isNotEmpty) { 565 if (typeFormals.isNotEmpty) {
557 classDef = _defineClassTypeArguments(classElem, typeFormals, classDef); 566 classDef = _defineClassTypeArguments(classElem, typeFormals, classDef);
558 } 567 }
559 568
560 body = <JS.Statement>[classDef]; 569 body = <JS.Statement>[classDef];
561 _emitStaticFields(staticFields, classElem, body); 570 _emitStaticFields(staticFields, classElem, body);
562 _registerExtensionType(classElem, body); 571 _registerExtensionType(classElem, body);
563 return _statement(body); 572 return _statement(body);
564 } 573 }
565 574
566 JS.Expression _defineClass(ClassElement classElem, 575 void _defineClass(ClassElement classElem, JS.Expression className,
567 JS.ClassExpression classExpr, List<JS.Statement> body) { 576 JS.ClassExpression classExpr, List<JS.Statement> body) {
568 JS.Expression className;
569 if (classElem.typeParameters.isNotEmpty) { 577 if (classElem.typeParameters.isNotEmpty) {
570 // Generic classes will be defined inside a function that closes over the 578 // Generic classes will be defined inside a function that closes over the
571 // type parameter. So we can use their local variable name directly. 579 // type parameter. So we can use their local variable name directly.
572 className = classExpr.name;
573 body.add(new JS.ClassDeclaration(classExpr)); 580 body.add(new JS.ClassDeclaration(classExpr));
574 } else { 581 } else {
575 className = _emitTopLevelName(classElem);
576 body.add(js.statement('# = #;', [className, classExpr])); 582 body.add(js.statement('# = #;', [className, classExpr]));
577 } 583 }
578 return className; 584 }
585
586 void _emitVirtualFieldSymbols(ClassElement elem, List<JS.Statement> body) {
587 if (_virtualFieldSymbols[elem] == null) return;
588 body.addAll(_virtualFieldSymbols[elem]);
579 } 589 }
580 590
581 List<JS.Identifier> _emitTypeFormals(List<TypeParameterElement> typeFormals) { 591 List<JS.Identifier> _emitTypeFormals(List<TypeParameterElement> typeFormals) {
582 return typeFormals 592 return typeFormals
583 .map((t) => new JS.Identifier(t.name)) 593 .map((t) => new JS.Identifier(t.name))
584 .toList(growable: false); 594 .toList(growable: false);
585 } 595 }
586 596
587 /// Emits a field declaration for TypeScript & Closure's ES6_TYPED 597 /// Emits a field declaration for TypeScript & Closure's ES6_TYPED
588 /// (e.g. `class Foo { i: string; }`) 598 /// (e.g. `class Foo { i: string; }`)
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 [value], js.statement('{ this.# = #; }', [name, value])); 755 [value], js.statement('{ this.# = #; }', [name, value]));
746 method = new JS.Method(_elementMemberName(field.setter), fn, 756 method = new JS.Method(_elementMemberName(field.setter), fn,
747 isSetter: true); 757 isSetter: true);
748 jsMethods.add(method); 758 jsMethods.add(method);
749 } 759 }
750 } 760 }
751 } 761 }
752 return jsMethods; 762 return jsMethods;
753 } 763 }
754 764
755 List<JS.Method> _emitClassMethods(ClassDeclaration node, 765 List<JS.Method> _emitClassMethods(
756 List<ConstructorDeclaration> ctors, List<FieldDeclaration> fields) { 766 ClassDeclaration node,
767 List<ConstructorDeclaration> ctors,
768 List<FieldDeclaration> fields,
769 JS.Expression className,
770 ClassElement classElem) {
Jennifer Messerly 2016/04/25 22:47:04 This parameter isn't needed. See the very next li
Harry Terkelsen 2016/04/26 18:29:27 Done.
757 var element = node.element; 771 var element = node.element;
758 var type = element.type; 772 var type = element.type;
759 var isObject = type.isObject; 773 var isObject = type.isObject;
760 774
761 // Iff no constructor is specified for a class C, it implicitly has a 775 // Iff no constructor is specified for a class C, it implicitly has a
762 // default constructor `C() : super() {}`, unless C is class Object. 776 // default constructor `C() : super() {}`, unless C is class Object.
763 var jsMethods = <JS.Method>[]; 777 var jsMethods = <JS.Method>[];
764 if (ctors.isEmpty && !isObject) { 778 if (ctors.isEmpty && !isObject) {
765 jsMethods.add(_emitImplicitConstructor(node, fields)); 779 jsMethods.add(_emitImplicitConstructor(node, fields));
766 } 780 }
767 781
768 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; 782 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null;
769 var superclasses = getSuperclasses(element); 783 var superclasses = getSuperclasses(element);
770 784
771 bool hasIterator = false; 785 bool hasIterator = false;
772 for (var m in node.members) { 786 for (var m in node.members) {
773 if (m is ConstructorDeclaration) { 787 if (m is ConstructorDeclaration) {
774 jsMethods.add(_emitConstructor(m, type, fields, isObject)); 788 jsMethods.add(_emitConstructor(m, type, fields, isObject));
775 } else if (m is MethodDeclaration) { 789 } else if (m is MethodDeclaration) {
776 jsMethods.add(_emitMethodDeclaration(type, m)); 790 jsMethods.add(_emitMethodDeclaration(type, m));
777 791
778 if (m.element is PropertyAccessorElement) { 792 if (m.element is PropertyAccessorElement) {
779 jsMethods.add(_emitSuperAccessorWrapper(m, type, superclasses)); 793 jsMethods.add(_emitSuperAccessorWrapper(m, type, superclasses));
780 } 794 }
781 795
782 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { 796 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') {
783 hasIterator = true; 797 hasIterator = true;
784 jsMethods.add(_emitIterable(type)); 798 jsMethods.add(_emitIterable(type));
785 } 799 }
786 } else if (m is FieldDeclaration && _extensionTypes.contains(element)) { 800 } else if (m is FieldDeclaration) {
787 jsMethods.addAll(_emitNativeFieldAccessors(m)); 801 if (_extensionTypes.contains(element)) {
802 jsMethods.addAll(_emitNativeFieldAccessors(m));
803 continue;
804 }
805 if (m.isStatic) continue;
806 for (VariableDeclaration field in m.fields.variables) {
807 var propertyOverrideResult = checkForPropertyOverride(
808 field.element, superclasses, _extensionTypes);
809 if (propertyOverrideResult.foundGetter ||
Jennifer Messerly 2016/04/25 22:47:04 consider: a shorter name here. "overrideInfo" or
Harry Terkelsen 2016/04/26 18:29:27 Done.
810 propertyOverrideResult.foundSetter) {
811 jsMethods.addAll(
812 _emitVirtualFieldAccessor(field, type, className, classElem));
Jennifer Messerly 2016/04/25 22:47:04 fyi -- you probably don't need to pass classElem o
Harry Terkelsen 2016/04/26 18:29:27 Done.
813 }
814 }
788 } 815 }
789 } 816 }
790 817
791 // If the type doesn't have an `iterator`, but claims to implement Iterable, 818 // If the type doesn't have an `iterator`, but claims to implement Iterable,
792 // we inject the adaptor method here, as it's less code size to put the 819 // we inject the adaptor method here, as it's less code size to put the
793 // helper on a parent class. This pattern is common in the core libraries 820 // helper on a parent class. This pattern is common in the core libraries
794 // (e.g. IterableMixin<E> and IterableBase<E>). 821 // (e.g. IterableMixin<E> and IterableBase<E>).
795 // 822 //
796 // (We could do this same optimization for any interface with an `iterator` 823 // (We could do this same optimization for any interface with an `iterator`
797 // method, but that's more expensive to check for, so it doesn't seem worth 824 // method, but that's more expensive to check for, so it doesn't seem worth
798 // it. The above case for an explicit `iterator` method will catch those.) 825 // it. The above case for an explicit `iterator` method will catch those.)
799 if (!hasJsPeer && !hasIterator && _implementsIterable(type)) { 826 if (!hasJsPeer && !hasIterator && _implementsIterable(type)) {
800 jsMethods.add(_emitIterable(type)); 827 jsMethods.add(_emitIterable(type));
801 } 828 }
802 829
803 return jsMethods.where((m) => m != null).toList(growable: false); 830 return jsMethods.where((m) => m != null).toList(growable: false);
804 } 831 }
805 832
833 /// This is called whenever a derived class needs to introduce a new field,
834 /// shadowing a field or getter/setter pair on its parent.
835 ///
836 /// This is important because otherwise, trying to read or write the field
837 /// would end up calling the getter or setter, and one of those might not even
838 /// exist, resulting in a runtime error. Even if they did exist, that's the
839 /// wrong behavior if a new field was declared.
840 List<JS.Method> _emitVirtualFieldAccessor(VariableDeclaration field,
841 InterfaceType type, JS.Expression className, ClassElement classElem) {
842 var virtualField = _emitVirtualFieldSymbol(field, className, classElem);
843 var result = <JS.Method>[];
844 var name = _emitMemberName(field.element.name, type: type);
845 var getter = js.call('function() { return this[#]; }', [virtualField]);
846 result.add(new JS.Method(name, getter, isGetter: true));
847
848 if (field.isFinal) {
849 var setter = js.call(
850 'function(value) {'
Jennifer Messerly 2016/04/25 22:47:04 style comment: triple quote style is nicer for the
Harry Terkelsen 2016/04/26 18:29:27 Done.
851 ' var f = this[#];'
852 ' if (f === undefined) {'
Jennifer Messerly 2016/04/25 22:47:04 Hmmmm, I'm a little confused about what's going on
Harry Terkelsen 2016/04/26 18:29:27 Done.
853 ' this[#] = value;'
854 ' } else {'
855 ' super[#] = value;'
856 ' }'
857 '}',
858 [virtualField, virtualField, name]);
859 result.add(new JS.Method(name, setter, isSetter: true));
860 } else {
861 var setter =
862 js.call('function(value) { this[#] = value; }', [virtualField]);
863 result.add(new JS.Method(name, setter, isSetter: true));
864 }
865
866 return result;
867 }
868
869 /// Emit a getter or setter that simply forwards to the superclass getter or
870 /// setter. This is needed because in ES6, if you only override a getter
871 /// (alternatively, a setter), then there is an implicit override of the
872 /// setter (alternatively, the getter) that does nothing.
806 JS.Method _emitSuperAccessorWrapper(MethodDeclaration method, 873 JS.Method _emitSuperAccessorWrapper(MethodDeclaration method,
807 InterfaceType type, List<ClassElement> superclasses) { 874 InterfaceType type, List<ClassElement> superclasses) {
808 var methodElement = method.element as PropertyAccessorElement; 875 var methodElement = method.element as PropertyAccessorElement;
809 var field = methodElement.variable; 876 var field = methodElement.variable;
810 if (!field.isSynthetic) return null; 877 if (!field.isSynthetic) return null;
811 var propertyOverrideResult = checkForPropertyOverride( 878 var propertyOverrideResult = checkForPropertyOverride(
812 methodElement.variable, superclasses, _extensionTypes); 879 methodElement.variable, superclasses, _extensionTypes);
813 880
814 // Generate a corresponding virtual getter / setter. 881 // Generate a corresponding virtual getter / setter.
815 var name = _elementMemberName(methodElement, 882 var name = _elementMemberName(methodElement,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 newBaseClass = js.call('dart.global.#', [jsPeerName]); 971 newBaseClass = js.call('dart.global.#', [jsPeerName]);
905 } else if (_hasDeferredSupertype.contains(classElem)) { 972 } else if (_hasDeferredSupertype.contains(classElem)) {
906 newBaseClass = _emitTypeName(classElem.type.superclass); 973 newBaseClass = _emitTypeName(classElem.type.superclass);
907 } 974 }
908 if (newBaseClass != null) { 975 if (newBaseClass != null) {
909 body.add( 976 body.add(
910 js.statement('dart.setBaseClass(#, #);', [className, newBaseClass])); 977 js.statement('dart.setBaseClass(#, #);', [className, newBaseClass]));
911 } 978 }
912 } 979 }
913 980
914 /// Emits instance fields, if they are virtual
915 /// (in other words, they override a getter/setter pair).
916 void _emitVirtualFields(
917 ClassElement classElement,
918 List<FieldDeclaration> fields,
919 JS.Expression className,
920 List<JS.Statement> body) {
921 List<ClassElement> superclasses = getSuperclasses(classElement);
922 for (FieldDeclaration member in fields) {
923 for (VariableDeclaration field in member.fields.variables) {
924 var propertyOverrideResult = checkForPropertyOverride(
925 field.element, superclasses, _extensionTypes);
926 if (propertyOverrideResult.foundGetter ||
927 propertyOverrideResult.foundSetter) {
928 body.add(_overrideField(className, field.element));
929 }
930 }
931 }
932 }
933
934 void _defineNamedConstructors(List<ConstructorDeclaration> ctors, 981 void _defineNamedConstructors(List<ConstructorDeclaration> ctors,
935 List<JS.Statement> body, JS.Expression className) { 982 List<JS.Statement> body, JS.Expression className) {
936 for (ConstructorDeclaration member in ctors) { 983 for (ConstructorDeclaration member in ctors) {
937 if (member.name != null && member.factoryKeyword == null) { 984 if (member.name != null && member.factoryKeyword == null) {
938 body.add(js.statement('dart.defineNamedConstructor(#, #);', 985 body.add(js.statement('dart.defineNamedConstructor(#, #);',
939 [className, _emitMemberName(member.name.name, isStatic: true)])); 986 [className, _emitMemberName(member.name.name, isStatic: true)]));
940 } 987 }
941 } 988 }
942 } 989 }
943 990
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 if (_extensionTypes.contains(element)) types.add(element); 1177 if (_extensionTypes.contains(element)) types.add(element);
1131 for (var m in type.mixins.reversed) { 1178 for (var m in type.mixins.reversed) {
1132 _collectExtensions(m, types); 1179 _collectExtensions(m, types);
1133 } 1180 }
1134 for (var i in type.interfaces) { 1181 for (var i in type.interfaces) {
1135 _collectExtensions(i, types); 1182 _collectExtensions(i, types);
1136 } 1183 }
1137 _collectExtensions(type.superclass, types); 1184 _collectExtensions(type.superclass, types);
1138 } 1185 }
1139 1186
1140 JS.Statement _overrideField(JS.Expression className, FieldElement e) {
1141 var cls = e.enclosingElement;
1142 return js.statement('dart.virtualField(#, #)',
1143 [className, _emitMemberName(e.name, type: cls.type)]);
1144 }
1145
1146 /// Generates the implicit default constructor for class C of the form 1187 /// Generates the implicit default constructor for class C of the form
1147 /// `C() : super() {}`. 1188 /// `C() : super() {}`.
1148 JS.Method _emitImplicitConstructor( 1189 JS.Method _emitImplicitConstructor(
1149 ClassDeclaration node, List<FieldDeclaration> fields) { 1190 ClassDeclaration node, List<FieldDeclaration> fields) {
1150 assert(_hasUnnamedConstructor(node.element) == fields.isNotEmpty); 1191 assert(_hasUnnamedConstructor(node.element) == fields.isNotEmpty);
1151 1192
1152 // If we don't have a method body, skip this. 1193 // If we don't have a method body, skip this.
1153 var superCall = _superConstructorCall(node.element); 1194 var superCall = _superConstructorCall(node.element);
1154 if (fields.isEmpty && superCall == null) return null; 1195 if (fields.isEmpty && superCall == null) return null;
1155 1196
(...skipping 2510 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 return _privateNames 3707 return _privateNames
3667 .putIfAbsent(library, () => new HashMap()) 3708 .putIfAbsent(library, () => new HashMap())
3668 .putIfAbsent(name, () { 3709 .putIfAbsent(name, () {
3669 var id = new JS.TemporaryId(name); 3710 var id = new JS.TemporaryId(name);
3670 _moduleItems.add( 3711 _moduleItems.add(
3671 js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")])); 3712 js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
3672 return id; 3713 return id;
3673 }); 3714 });
3674 } 3715 }
3675 3716
3717 JS.TemporaryId _emitVirtualFieldSymbol(VariableDeclaration field,
3718 JS.Expression className, ClassElement classElem) {
3719 return _virtualFields.putIfAbsent(field, () {
3720 var fieldName = _emitMemberName(field.element.name,
3721 type: (field.element.enclosingElement as ClassElement).type);
3722 var id = new JS.TemporaryId(field.name.name);
3723 _virtualFieldSymbols.putIfAbsent(classElem, () => <JS.Statement>[]).add(js
3724 .statement('const # = Symbol(#.name + "." + #.toString());',
3725 [id, className, fieldName]));
3726 return id;
3727 });
3728 }
3729
3676 bool _externalOrNative(node) => 3730 bool _externalOrNative(node) =>
3677 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; 3731 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody;
3678 3732
3679 FunctionBody _functionBody(node) => 3733 FunctionBody _functionBody(node) =>
3680 node is FunctionDeclaration ? node.functionExpression.body : node.body; 3734 node is FunctionDeclaration ? node.functionExpression.body : node.body;
3681 3735
3682 /// Returns the canonical name to refer to the Dart library. 3736 /// Returns the canonical name to refer to the Dart library.
3683 JS.Identifier emitLibraryName(LibraryElement library) { 3737 JS.Identifier emitLibraryName(LibraryElement library) {
3684 // It's either one of the libraries in this module, or it's an import. 3738 // It's either one of the libraries in this module, or it's an import.
3685 return _libraries[library] ?? 3739 return _libraries[library] ??
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
3788 } 3842 }
3789 3843
3790 bool isLibraryPrefix(Expression node) => 3844 bool isLibraryPrefix(Expression node) =>
3791 node is SimpleIdentifier && node.staticElement is PrefixElement; 3845 node is SimpleIdentifier && node.staticElement is PrefixElement;
3792 3846
3793 LibraryElement _getLibrary(AnalysisContext c, String uri) => 3847 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
3794 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 3848 c.computeLibraryElement(c.sourceFactory.forUri(uri));
3795 3849
3796 bool _isDartRuntime(LibraryElement l) => 3850 bool _isDartRuntime(LibraryElement l) =>
3797 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 3851 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | test/codegen/expect/fieldtest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698