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

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

Issue 2301973002: More DDC mirrors support (Closed)
Patch Set: Format fixes per comments Created 4 years, 3 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 | « no previous file | pkg/dev_compiler/test/browser/language_tests.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 import 'dart:math' show min, max; 6 import 'dart:math' show min, max;
7 7
8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 _defineClass(classElem, className, classExpr, isCallable, body); 726 _defineClass(classElem, className, classExpr, isCallable, body);
727 727
728 // Emit things that come after the ES6 `class ... { ... }`. 728 // Emit things that come after the ES6 `class ... { ... }`.
729 var jsPeerName = _getJSPeerName(classElem); 729 var jsPeerName = _getJSPeerName(classElem);
730 _setBaseClass(classElem, className, jsPeerName, body); 730 _setBaseClass(classElem, className, jsPeerName, body);
731 731
732 _emitClassTypeTests(classElem, className, body); 732 _emitClassTypeTests(classElem, className, body);
733 733
734 _defineNamedConstructors(ctors, body, className, isCallable); 734 _defineNamedConstructors(ctors, body, className, isCallable);
735 _emitVirtualFieldSymbols(virtualFieldSymbols, body); 735 _emitVirtualFieldSymbols(virtualFieldSymbols, body);
736 _emitClassSignature(methods, classElem, ctors, extensions, className, body); 736 _emitClassSignature(
737 methods, allFields, classElem, ctors, extensions, className, body);
737 _defineExtensionMembers(extensions, className, body); 738 _defineExtensionMembers(extensions, className, body);
738 _emitClassMetadata(node.metadata, className, body); 739 _emitClassMetadata(node.metadata, className, body);
739 740
740 JS.Statement classDef = _statement(body); 741 JS.Statement classDef = _statement(body);
741 var typeFormals = classElem.typeParameters; 742 var typeFormals = classElem.typeParameters;
742 if (typeFormals.isNotEmpty) { 743 if (typeFormals.isNotEmpty) {
743 classDef = _defineClassTypeArguments(classElem, typeFormals, classDef); 744 classDef = _defineClassTypeArguments(classElem, typeFormals, classDef);
744 } 745 }
745 746
746 body = <JS.Statement>[classDef]; 747 body = <JS.Statement>[classDef];
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 body.add(js.statement('dart.defineExtensionMembers(#, #);', [ 1644 body.add(js.statement('dart.defineExtensionMembers(#, #);', [
1644 className, 1645 className,
1645 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) 1646 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4)
1646 ])); 1647 ]));
1647 } 1648 }
1648 } 1649 }
1649 1650
1650 /// Emit the signature on the class recording the runtime type information 1651 /// Emit the signature on the class recording the runtime type information
1651 void _emitClassSignature( 1652 void _emitClassSignature(
1652 List<MethodDeclaration> methods, 1653 List<MethodDeclaration> methods,
1654 List<FieldDeclaration> fields,
1653 ClassElement classElem, 1655 ClassElement classElem,
1654 List<ConstructorDeclaration> ctors, 1656 List<ConstructorDeclaration> ctors,
1655 List<ExecutableElement> extensions, 1657 List<ExecutableElement> extensions,
1656 JS.Expression className, 1658 JS.Expression className,
1657 List<JS.Statement> body) { 1659 List<JS.Statement> body) {
1658 if (classElem.interfaces.isNotEmpty) { 1660 if (classElem.interfaces.isNotEmpty) {
1659 body.add(js.statement('#[dart.implements] = () => #;', [ 1661 body.add(js.statement('#[dart.implements] = () => #;', [
1660 className, 1662 className,
1661 new JS.ArrayInitializer( 1663 new JS.ArrayInitializer(
1662 new List<JS.Expression>.from(classElem.interfaces.map(_emitType))) 1664 new List<JS.Expression>.from(classElem.interfaces.map(_emitType)))
1663 ])); 1665 ]));
1664 } 1666 }
1665 1667
1666 var tStatics = <JS.Property>[]; 1668 var tStaticMethods = <JS.Property>[];
1667 var tMethods = <JS.Property>[]; 1669 var tInstanceMethods = <JS.Property>[];
1670 var tStaticGetters = <JS.Property>[];
1671 var tInstanceGetters = <JS.Property>[];
1672 var tStaticSetters = <JS.Property>[];
1673 var tInstanceSetters = <JS.Property>[];
1668 var sNames = <JS.Expression>[]; 1674 var sNames = <JS.Expression>[];
1669 for (MethodDeclaration node in methods) { 1675 for (MethodDeclaration node in methods) {
1670 if (!(node.isSetter || node.isGetter || node.isAbstract)) { 1676 var name = node.name.name;
1671 var name = node.name.name; 1677 var element = node.element;
1672 var element = node.element; 1678 // TODO(vsm): Clean up all the nasty duplication.
1673 var inheritedElement = 1679 if (node.isAbstract) {
1674 classElem.lookUpInheritedConcreteMethod(name, currentLibrary); 1680 continue;
1675 if (inheritedElement != null && inheritedElement.type == element.type) { 1681 }
1676 continue; 1682
1677 } 1683 Function lookup;
1678 var memberName = _elementMemberName(element, 1684 List<JS.Property> tMember;
1679 useExtension: _extensionTypes.isNativeClass(classElem)); 1685 JS.Expression type;
1680 var type = _emitFunctionType(element.type, 1686 if (node.isGetter) {
1681 nameType: options.hoistSignatureTypes, 1687 lookup = classElem.lookUpInheritedConcreteGetter;
1682 hoistType: options.hoistSignatureTypes, 1688 tMember = node.isStatic ? tStaticGetters : tInstanceGetters;
1683 definite: true); 1689 } else if (node.isSetter) {
1684 var property = new JS.Property(memberName, type); 1690 lookup = classElem.lookUpInheritedConcreteSetter;
1685 if (node.isStatic) { 1691 tMember = node.isStatic ? tStaticSetters : tInstanceSetters;
1686 tStatics.add(property); 1692 } else {
1687 sNames.add(memberName); 1693 // Method
1688 } else { 1694 lookup = classElem.lookUpInheritedConcreteMethod;
1689 tMethods.add(property); 1695 tMember = node.isStatic ? tStaticMethods : tInstanceMethods;
1690 } 1696 }
1697
1698 type = _emitAnnotatedFunctionType(element.type, node.metadata,
1699 parameters: node.parameters?.parameters,
1700 nameType: options.hoistSignatureTypes,
1701 hoistType: options.hoistSignatureTypes,
1702 definite: true);
1703
1704 var inheritedElement = lookup(name, currentLibrary);
1705 if (inheritedElement != null && inheritedElement.type == element.type) {
1706 continue;
1707 }
1708 var memberName = _elementMemberName(element,
1709 useExtension: _extensionTypes.isNativeClass(classElem));
1710 var property = new JS.Property(memberName, type);
1711 tMember.add(property);
1712 // TODO(vsm): Why do we need this?
1713 if (node.isStatic && !node.isGetter && !node.isSetter) {
1714 sNames.add(memberName);
1691 } 1715 }
1692 } 1716 }
1693 1717
1718 var tInstanceFields = <JS.Property>[];
1719 var tStaticFields = <JS.Property>[];
1720 for (FieldDeclaration node in fields) {
1721 for (VariableDeclaration field in node.fields.variables) {
1722 var element = field.element as FieldElement;
1723 var memberName = _elementMemberName(element.getter,
1724 useExtension: _extensionTypes.isNativeClass(classElem));
1725 var type = _emitAnnotatedType(element.type, node.metadata);
1726 var property = new JS.Property(memberName, type);
1727 (node.isStatic ? tStaticFields : tInstanceFields).add(property);
1728 }
1729 }
1730
1694 var tCtors = <JS.Property>[]; 1731 var tCtors = <JS.Property>[];
1695 for (ConstructorDeclaration node in ctors) { 1732 for (ConstructorDeclaration node in ctors) {
1696 var memberName = _constructorName(node.element); 1733 var memberName = _constructorName(node.element);
1697 var element = node.element; 1734 var element = node.element;
1698 var type = _emitFunctionType(element.type, 1735 var type = _emitAnnotatedFunctionType(element.type, node.metadata,
1699 parameters: node.parameters.parameters, 1736 parameters: node.parameters.parameters,
1700 nameType: options.hoistSignatureTypes, 1737 nameType: options.hoistSignatureTypes,
1701 hoistType: options.hoistSignatureTypes, 1738 hoistType: options.hoistSignatureTypes,
1702 definite: true); 1739 definite: true);
1703 var property = new JS.Property(memberName, type); 1740 var property = new JS.Property(memberName, type);
1704 tCtors.add(property); 1741 tCtors.add(property);
1705 } 1742 }
1706 1743
1707 JS.Property build(String name, List<JS.Property> elements) { 1744 JS.Property build(String name, List<JS.Property> elements) {
1708 var o = 1745 var o =
1709 new JS.ObjectInitializer(elements, multiline: elements.length > 1); 1746 new JS.ObjectInitializer(elements, multiline: elements.length > 1);
1747 // TODO(vsm): Remove
1710 var e = js.call('() => #', o); 1748 var e = js.call('() => #', o);
1711 return new JS.Property(_propertyName(name), e); 1749 return new JS.Property(_propertyName(name), e);
1712 } 1750 }
1713 1751
1714 var sigFields = <JS.Property>[]; 1752 var sigFields = <JS.Property>[];
1715 if (!tCtors.isEmpty) sigFields.add(build('constructors', tCtors)); 1753 if (!tCtors.isEmpty) {
1716 if (!tMethods.isEmpty) sigFields.add(build('methods', tMethods)); 1754 sigFields.add(build('constructors', tCtors));
1717 if (!tStatics.isEmpty) { 1755 }
1756 if (!tInstanceFields.isEmpty) {
1757 sigFields.add(build('fields', tInstanceFields));
1758 }
1759 if (!tInstanceGetters.isEmpty) {
1760 sigFields.add(build('getters', tInstanceGetters));
1761 }
1762 if (!tInstanceSetters.isEmpty) {
1763 sigFields.add(build('setters', tInstanceSetters));
1764 }
1765 if (!tInstanceMethods.isEmpty) {
1766 sigFields.add(build('methods', tInstanceMethods));
1767 }
1768 if (!tStaticFields.isEmpty) {
1769 sigFields.add(build('sfields', tStaticFields));
1770 }
1771 if (!tStaticGetters.isEmpty) {
1772 sigFields.add(build('sgetters', tStaticGetters));
1773 }
1774 if (!tStaticSetters.isEmpty) {
1775 sigFields.add(build('ssetters', tStaticSetters));
1776 }
1777 if (!tStaticMethods.isEmpty) {
1718 assert(!sNames.isEmpty); 1778 assert(!sNames.isEmpty);
1779 // TODO(vsm): Why do we need this names field?
1719 var aNames = new JS.Property( 1780 var aNames = new JS.Property(
1720 _propertyName('names'), new JS.ArrayInitializer(sNames)); 1781 _propertyName('names'), new JS.ArrayInitializer(sNames));
1721 sigFields.add(build('statics', tStatics)); 1782 sigFields.add(build('statics', tStaticMethods));
1722 sigFields.add(aNames); 1783 sigFields.add(aNames);
1723 } 1784 }
1724 if (!sigFields.isEmpty || extensions.isNotEmpty) { 1785 if (!sigFields.isEmpty || extensions.isNotEmpty) {
1725 var sig = new JS.ObjectInitializer(sigFields); 1786 var sig = new JS.ObjectInitializer(sigFields);
1726 body.add(js.statement('dart.setSignature(#, #);', [className, sig])); 1787 body.add(js.statement('dart.setSignature(#, #);', [className, sig]));
1727 } 1788 }
1728 // Add static property dart._runtimeType to Object. 1789 // Add static property dart._runtimeType to Object.
1729 // All other Dart classes will (statically) inherit this property. 1790 // All other Dart classes will (statically) inherit this property.
1730 if (classElem == objectClass) { 1791 if (classElem == objectClass) {
1731 body.add(js.statement('dart.tagComputed(#, () => #.#);', 1792 body.add(js.statement('dart.tagComputed(#, () => #.#);',
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
2662 2723
2663 var type = declaration ? emitTypeRef(element.type) : null; 2724 var type = declaration ? emitTypeRef(element.type) : null;
2664 return new JS.Identifier(element.name, type: type); 2725 return new JS.Identifier(element.name, type: type);
2665 } 2726 }
2666 2727
2667 List<Annotation> _parameterMetadata(FormalParameter p) => 2728 List<Annotation> _parameterMetadata(FormalParameter p) =>
2668 (p is NormalFormalParameter) 2729 (p is NormalFormalParameter)
2669 ? p.metadata 2730 ? p.metadata
2670 : (p as DefaultFormalParameter).parameter.metadata; 2731 : (p as DefaultFormalParameter).parameter.metadata;
2671 2732
2733 // Wrap a result - usually a type - with its metadata. The runtime is
2734 // responsible for unpacking this.
2735 JS.Expression _emitAnnotatedResult(
2736 JS.Expression result, List<Annotation> metadata) {
2737 if (options.emitMetadata && metadata != null && metadata.isNotEmpty) {
2738 result = new JS.ArrayInitializer(
2739 [result]..addAll(metadata.map(_instantiateAnnotation)));
2740 }
2741 return result;
2742 }
2743
2744 JS.Expression _emitAnnotatedType(DartType type, List<Annotation> metadata,
2745 {bool nameType: true, bool hoistType: true}) {
2746 metadata ??= [];
2747 var typeName = _emitType(type, nameType: nameType, hoistType: hoistType);
2748 return _emitAnnotatedResult(typeName, metadata);
2749 }
2750
2672 JS.ArrayInitializer _emitTypeNames( 2751 JS.ArrayInitializer _emitTypeNames(
2673 List<DartType> types, List<FormalParameter> parameters, 2752 List<DartType> types, List<FormalParameter> parameters,
2674 {bool nameType: true, bool hoistType: true}) { 2753 {bool nameType: true, bool hoistType: true}) {
2675 var result = <JS.Expression>[]; 2754 var result = <JS.Expression>[];
2676 for (int i = 0; i < types.length; ++i) { 2755 for (int i = 0; i < types.length; ++i) {
2677 var metadata = 2756 var metadata = parameters != null
2678 parameters != null ? _parameterMetadata(parameters[i]) : []; 2757 ? _parameterMetadata(parameters[i])
2679 var typeName = 2758 : <Annotation>[];
2680 _emitType(types[i], nameType: nameType, hoistType: hoistType); 2759 result.add(_emitAnnotatedType(types[i], metadata));
2681 var value = typeName;
2682 if (options.emitMetadata && metadata.isNotEmpty) {
2683 value = new JS.ArrayInitializer(
2684 [typeName]..addAll(metadata.map(_instantiateAnnotation)));
2685 }
2686 result.add(value);
2687 } 2760 }
2688 return new JS.ArrayInitializer(result); 2761 return new JS.ArrayInitializer(result);
2689 } 2762 }
2690 2763
2691 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { 2764 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) {
2692 var properties = <JS.Property>[]; 2765 var properties = <JS.Property>[];
2693 types.forEach((name, type) { 2766 types.forEach((name, type) {
2694 var key = _propertyName(name); 2767 var key = _propertyName(name);
2695 var value = _emitType(type); 2768 var value = _emitType(type);
2696 properties.add(new JS.Property(key, value)); 2769 properties.add(new JS.Property(key, value));
(...skipping 14 matching lines...) Expand all
2711 lowerTypedef: lowerTypedef, 2784 lowerTypedef: lowerTypedef,
2712 nameType: nameType, 2785 nameType: nameType,
2713 hoistType: hoistType); 2786 hoistType: hoistType);
2714 var helper = (definite) ? 'definiteFunctionType' : 'functionType'; 2787 var helper = (definite) ? 'definiteFunctionType' : 'functionType';
2715 var fullType = js.call('dart.${helper}(#)', [parts]); 2788 var fullType = js.call('dart.${helper}(#)', [parts]);
2716 if (!nameType) return fullType; 2789 if (!nameType) return fullType;
2717 return _typeTable.nameType(type, fullType, 2790 return _typeTable.nameType(type, fullType,
2718 hoistType: hoistType, definite: definite); 2791 hoistType: hoistType, definite: definite);
2719 } 2792 }
2720 2793
2794 JS.Expression _emitAnnotatedFunctionType(
2795 FunctionType type, List<Annotation> metadata,
2796 {List<FormalParameter> parameters,
2797 bool lowerTypedef: false,
2798 bool nameType: true,
2799 bool hoistType: true,
2800 bool definite: false}) {
2801 var result = _emitFunctionType(type,
2802 parameters: parameters,
2803 lowerTypedef: lowerTypedef,
2804 nameType: nameType,
2805 hoistType: hoistType,
2806 definite: definite);
2807 return _emitAnnotatedResult(result, metadata);
2808 }
2809
2721 /// Emit the pieces of a function type, as an array of return type, 2810 /// Emit the pieces of a function type, as an array of return type,
2722 /// regular args, and optional/named args. 2811 /// regular args, and optional/named args.
2723 List<JS.Expression> _emitFunctionTypeParts(FunctionType type, 2812 List<JS.Expression> _emitFunctionTypeParts(FunctionType type,
2724 {List<FormalParameter> parameters, 2813 {List<FormalParameter> parameters,
2725 bool lowerTypedef: false, 2814 bool lowerTypedef: false,
2726 bool nameType: true, 2815 bool nameType: true,
2727 bool hoistType: true}) { 2816 bool hoistType: true}) {
2728 var parameterTypes = type.normalParameterTypes; 2817 var parameterTypes = type.normalParameterTypes;
2729 var optionalTypes = type.optionalParameterTypes; 2818 var optionalTypes = type.optionalParameterTypes;
2730 var namedTypes = type.namedParameterTypes; 2819 var namedTypes = type.namedParameterTypes;
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after
5363 } 5452 }
5364 5453
5365 bool isLibraryPrefix(Expression node) => 5454 bool isLibraryPrefix(Expression node) =>
5366 node is SimpleIdentifier && node.staticElement is PrefixElement; 5455 node is SimpleIdentifier && node.staticElement is PrefixElement;
5367 5456
5368 LibraryElement _getLibrary(AnalysisContext c, String uri) => 5457 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
5369 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 5458 c.computeLibraryElement(c.sourceFactory.forUri(uri));
5370 5459
5371 bool _isDartRuntime(LibraryElement l) => 5460 bool _isDartRuntime(LibraryElement l) =>
5372 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 5461 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW
« no previous file with comments | « no previous file | pkg/dev_compiler/test/browser/language_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698