OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 mirrors_dart2js; | 5 library mirrors_dart2js; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:uri'; | 8 import 'dart:uri'; |
9 | 9 |
10 import '../../compiler.dart' as diagnostics; | 10 import '../../compiler.dart' as diagnostics; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } else if (type is FunctionType) { | 72 } else if (type is FunctionType) { |
73 return new Dart2JsFunctionTypeMirror(system, type, functionSignature); | 73 return new Dart2JsFunctionTypeMirror(system, type, functionSignature); |
74 } else if (type is VoidType) { | 74 } else if (type is VoidType) { |
75 return new Dart2JsVoidMirror(system, type); | 75 return new Dart2JsVoidMirror(system, type); |
76 } else if (type is TypedefType) { | 76 } else if (type is TypedefType) { |
77 return new Dart2JsTypedefMirror(system, type); | 77 return new Dart2JsTypedefMirror(system, type); |
78 } else if (type is MalformedType) { | 78 } else if (type is MalformedType) { |
79 // TODO(johnniwinther): We need a mirror on malformed types. | 79 // TODO(johnniwinther): We need a mirror on malformed types. |
80 return system.dynamicType; | 80 return system.dynamicType; |
81 } | 81 } |
82 throw new ArgumentError("Unexpected type $type of kind ${type.kind}"); | 82 _diagnosticListener.internalError( |
| 83 "Unexpected type $type of kind ${type.kind}"); |
| 84 system.compiler.internalError("Unexpected type $type of kind ${type.kind}"); |
83 } | 85 } |
84 | 86 |
85 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( | 87 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( |
86 Dart2JsContainerMirror library, Element element) { | 88 Dart2JsContainerMirror library, Element element) { |
87 if (element is SynthesizedConstructorElement) { | 89 if (element is SynthesizedConstructorElement) { |
88 return const <Dart2JsMemberMirror>[]; | 90 return const <Dart2JsMemberMirror>[]; |
89 } else if (element is VariableElement) { | 91 } else if (element is VariableElement) { |
90 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)]; | 92 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)]; |
91 } else if (element is FunctionElement) { | 93 } else if (element is FunctionElement) { |
92 return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(library, element)]; | 94 return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(library, element)]; |
93 } else if (element is AbstractFieldElement) { | 95 } else if (element is AbstractFieldElement) { |
94 var members = <Dart2JsMemberMirror>[]; | 96 var members = <Dart2JsMemberMirror>[]; |
95 if (element.getter != null) { | 97 if (element.getter != null) { |
96 members.add(new Dart2JsMethodMirror(library, element.getter)); | 98 members.add(new Dart2JsMethodMirror(library, element.getter)); |
97 } | 99 } |
98 if (element.setter != null) { | 100 if (element.setter != null) { |
99 members.add(new Dart2JsMethodMirror(library, element.setter)); | 101 members.add(new Dart2JsMethodMirror(library, element.setter)); |
100 } | 102 } |
101 return members; | 103 return members; |
102 } | 104 } |
103 throw new ArgumentError( | 105 library.mirrors.compiler.internalError( |
104 "Unexpected member type $element ${element.kind}"); | 106 "Unexpected member type $element ${element.kind}"); |
105 } | 107 } |
106 | 108 |
107 MethodMirror _convertElementMethodToMethodMirror(Dart2JsContainerMirror library, | 109 MethodMirror _convertElementMethodToMethodMirror(Dart2JsContainerMirror library, |
108 Element element) { | 110 Element element) { |
109 if (element is FunctionElement) { | 111 if (element is FunctionElement) { |
110 return new Dart2JsMethodMirror(library, element); | 112 return new Dart2JsMethodMirror(library, element); |
111 } else { | 113 } else { |
112 return null; | 114 return null; |
113 } | 115 } |
114 } | 116 } |
115 | 117 |
| 118 InstanceMirror _convertConstantToInstanceMirror(Dart2JsMirrorSystem mirrors, |
| 119 Constant constant) { |
| 120 if (constant is BoolConstant) { |
| 121 return new Dart2JsBoolConstantMirror(mirrors, constant); |
| 122 } else if (constant is NumConstant) { |
| 123 return new Dart2JsNumConstantMirror(mirrors, constant); |
| 124 } else if (constant is StringConstant) { |
| 125 return new Dart2JsStringConstantMirror(mirrors, constant); |
| 126 } else if (constant is ListConstant) { |
| 127 return new Dart2JsListConstantMirror(mirrors, constant); |
| 128 } else if (constant is MapConstant) { |
| 129 return new Dart2JsMapConstantMirror(mirrors, constant); |
| 130 } else if (constant is TypeConstant) { |
| 131 return new Dart2JsTypeConstantMirror(mirrors, constant); |
| 132 } else if (constant is FunctionConstant) { |
| 133 return new Dart2JsConstantMirror(mirrors, constant); |
| 134 } else if (constant is NullConstant) { |
| 135 return new Dart2JsNullConstantMirror(mirrors, constant); |
| 136 } else if (constant is ConstructedConstant) { |
| 137 return new Dart2JsConstructedConstantMirror(mirrors, constant); |
| 138 } |
| 139 mirrors.compiler.internalError("Unexpected constant $constant"); |
| 140 } |
| 141 |
116 class Dart2JsMethodKind { | 142 class Dart2JsMethodKind { |
117 static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular"); | 143 static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular"); |
118 static const Dart2JsMethodKind GENERATIVE = | 144 static const Dart2JsMethodKind GENERATIVE = |
119 const Dart2JsMethodKind("generative"); | 145 const Dart2JsMethodKind("generative"); |
120 static const Dart2JsMethodKind REDIRECTING = | 146 static const Dart2JsMethodKind REDIRECTING = |
121 const Dart2JsMethodKind("redirecting"); | 147 const Dart2JsMethodKind("redirecting"); |
122 static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const"); | 148 static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const"); |
123 static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory"); | 149 static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory"); |
124 static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter"); | 150 static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter"); |
125 static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter"); | 151 static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter"); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 459 } |
434 | 460 |
435 abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror | 461 abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror |
436 implements TypeMirror { | 462 implements TypeMirror { |
437 | 463 |
438 } | 464 } |
439 | 465 |
440 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { | 466 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { |
441 final Dart2JsMirrorSystem mirrors; | 467 final Dart2JsMirrorSystem mirrors; |
442 final Element _element; | 468 final Element _element; |
| 469 List<InstanceMirror> _metadata; |
443 | 470 |
444 Dart2JsElementMirror(this.mirrors, this._element) { | 471 Dart2JsElementMirror(this.mirrors, this._element) { |
445 assert (mirrors != null); | 472 assert (mirrors != null); |
446 assert (_element != null); | 473 assert (_element != null); |
447 } | 474 } |
448 | 475 |
449 String get simpleName => _element.name.slowToString(); | 476 String get simpleName => _element.name.slowToString(); |
450 | 477 |
451 String get displayName => simpleName; | 478 String get displayName => simpleName; |
452 | 479 |
453 SourceLocation get location => new Dart2JsSourceLocation( | 480 SourceLocation get location => new Dart2JsSourceLocation( |
454 _element.getCompilationUnit().script, | 481 _element.getCompilationUnit().script, |
455 mirrors.compiler.spanFromElement(_element)); | 482 mirrors.compiler.spanFromElement(_element)); |
456 | 483 |
457 String toString() => _element.toString(); | 484 String toString() => _element.toString(); |
458 | 485 |
459 int get hashCode => qualifiedName.hashCode; | 486 int get hashCode => qualifiedName.hashCode; |
| 487 |
| 488 List<InstanceMirror> get metadata { |
| 489 if (_metadata == null) { |
| 490 _metadata = <InstanceMirror>[]; |
| 491 for (MetadataAnnotation metadata in _element.metadata) { |
| 492 metadata.ensureResolved(mirrors.compiler); |
| 493 _metadata.add( |
| 494 _convertConstantToInstanceMirror(mirrors, metadata.value)); |
| 495 } |
| 496 } |
| 497 // TODO(johnniwinther): Return an unmodifiable list instead. |
| 498 return new List<InstanceMirror>.from(_metadata); |
| 499 } |
460 } | 500 } |
461 | 501 |
462 abstract class Dart2JsProxyMirror extends Dart2JsDeclarationMirror { | 502 abstract class Dart2JsProxyMirror extends Dart2JsDeclarationMirror { |
463 final Dart2JsMirrorSystem mirrors; | 503 final Dart2JsMirrorSystem mirrors; |
464 | 504 |
465 Dart2JsProxyMirror(this.mirrors); | 505 Dart2JsProxyMirror(this.mirrors); |
466 | 506 |
467 String get displayName => simpleName; | 507 String get displayName => simpleName; |
468 | 508 |
469 int get hashCode => qualifiedName.hashCode; | 509 int get hashCode => qualifiedName.hashCode; |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 } | 1119 } |
1080 | 1120 |
1081 | 1121 |
1082 //------------------------------------------------------------------------------ | 1122 //------------------------------------------------------------------------------ |
1083 // Types | 1123 // Types |
1084 //------------------------------------------------------------------------------ | 1124 //------------------------------------------------------------------------------ |
1085 | 1125 |
1086 abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror | 1126 abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror |
1087 implements Dart2JsTypeMirror { | 1127 implements Dart2JsTypeMirror { |
1088 final DartType _type; | 1128 final DartType _type; |
| 1129 List<InstanceMirror> _metadata; |
1089 | 1130 |
1090 Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, this._type) | 1131 Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, this._type) |
1091 : super(system); | 1132 : super(system); |
1092 | 1133 |
1093 String get simpleName => _type.name.slowToString(); | 1134 String get simpleName => _type.name.slowToString(); |
1094 | 1135 |
1095 SourceLocation get location { | 1136 SourceLocation get location { |
1096 var script = _type.element.getCompilationUnit().script; | 1137 var script = _type.element.getCompilationUnit().script; |
1097 return new Dart2JsSourceLocation(script, | 1138 return new Dart2JsSourceLocation(script, |
1098 mirrors.compiler.spanFromElement(_type.element)); | 1139 mirrors.compiler.spanFromElement(_type.element)); |
(...skipping 25 matching lines...) Expand all Loading... |
1124 | 1165 |
1125 Map<String, MethodMirror> get methods => const <String, MethodMirror>{}; | 1166 Map<String, MethodMirror> get methods => const <String, MethodMirror>{}; |
1126 | 1167 |
1127 Map<String, MethodMirror> get getters => const <String, MethodMirror>{}; | 1168 Map<String, MethodMirror> get getters => const <String, MethodMirror>{}; |
1128 | 1169 |
1129 Map<String, MethodMirror> get setters => const <String, MethodMirror>{}; | 1170 Map<String, MethodMirror> get setters => const <String, MethodMirror>{}; |
1130 | 1171 |
1131 Map<String, VariableMirror> get variables => const <String, VariableMirror>{}; | 1172 Map<String, VariableMirror> get variables => const <String, VariableMirror>{}; |
1132 | 1173 |
1133 ClassMirror get defaultFactory => null; | 1174 ClassMirror get defaultFactory => null; |
| 1175 |
| 1176 // TODO(johnniwinther): Should a type show the metadata of its declaration? |
| 1177 List<InstanceMirror> get metadata { |
| 1178 if (_metadata == null) { |
| 1179 var _metadata = <InstanceMirror>[]; |
| 1180 for (MetadataAnnotation metadata in _type.element.metadata) { |
| 1181 metadata.ensureResolved(mirrors.compiler); |
| 1182 _metadata.add( |
| 1183 _convertConstantToInstanceMirror(mirrors, metadata.value)); |
| 1184 } |
| 1185 } |
| 1186 // TODO(johnniwinther): Return an unmodifiable list instead. |
| 1187 return new List<InstanceMirror>.from(_metadata); |
| 1188 } |
1134 } | 1189 } |
1135 | 1190 |
1136 class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror | 1191 class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror |
1137 implements ClassMirror { | 1192 implements ClassMirror { |
1138 List<TypeMirror> _typeArguments; | 1193 List<TypeMirror> _typeArguments; |
1139 | 1194 |
1140 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system, | 1195 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system, |
1141 InterfaceType interfaceType) | 1196 InterfaceType interfaceType) |
1142 : super(system, interfaceType); | 1197 : super(system, interfaceType); |
1143 | 1198 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 var node = _variable.variables.parseNode(_diagnosticListener); | 1613 var node = _variable.variables.parseNode(_diagnosticListener); |
1559 if (node != null) { | 1614 if (node != null) { |
1560 var span = mirrors.compiler.spanFromNode(node, script.uri); | 1615 var span = mirrors.compiler.spanFromNode(node, script.uri); |
1561 return new Dart2JsSourceLocation(script, span); | 1616 return new Dart2JsSourceLocation(script, span); |
1562 } else { | 1617 } else { |
1563 var span = mirrors.compiler.spanFromElement(_variable); | 1618 var span = mirrors.compiler.spanFromElement(_variable); |
1564 return new Dart2JsSourceLocation(script, span); | 1619 return new Dart2JsSourceLocation(script, span); |
1565 } | 1620 } |
1566 } | 1621 } |
1567 } | 1622 } |
| 1623 |
| 1624 //////////////////////////////////////////////////////////////////////////////// |
| 1625 // Mirrors on constant values used for metadata. |
| 1626 //////////////////////////////////////////////////////////////////////////////// |
| 1627 |
| 1628 class Dart2JsConstantMirror extends InstanceMirror { |
| 1629 final Dart2JsMirrorSystem mirrors; |
| 1630 final Constant _constant; |
| 1631 |
| 1632 Dart2JsConstantMirror(this.mirrors, this._constant); |
| 1633 |
| 1634 ClassMirror get type { |
| 1635 return new Dart2JsClassMirror(mirrors, |
| 1636 _constant.computeType(mirrors.compiler).element); |
| 1637 } |
| 1638 |
| 1639 bool get hasReflectee => false; |
| 1640 |
| 1641 get reflectee { |
| 1642 // TODO(johnniwinther): Which exception/error should be thrown here? |
| 1643 throw new UnsupportedError('InstanceMirror does not have a reflectee'); |
| 1644 } |
| 1645 |
| 1646 Future<InstanceMirror> getField(String fieldName) { |
| 1647 // TODO(johnniwinther): Which exception/error should be thrown here? |
| 1648 throw new UnsupportedError('InstanceMirror does not have a reflectee'); |
| 1649 } |
| 1650 } |
| 1651 |
| 1652 class Dart2JsNullConstantMirror extends Dart2JsConstantMirror { |
| 1653 Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrors, NullConstant constant) |
| 1654 : super(mirrors, constant); |
| 1655 |
| 1656 NullConstant get _constant => super._constant; |
| 1657 |
| 1658 bool get hasReflectee => true; |
| 1659 |
| 1660 get reflectee => null; |
| 1661 } |
| 1662 |
| 1663 class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { |
| 1664 Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant) |
| 1665 : super(mirrors, constant); |
| 1666 |
| 1667 BoolConstant get _constant => super._constant; |
| 1668 |
| 1669 bool get hasReflectee => true; |
| 1670 |
| 1671 get reflectee => _constant is TrueConstant; |
| 1672 } |
| 1673 |
| 1674 class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { |
| 1675 Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1676 StringConstant constant) |
| 1677 : super(mirrors, constant); |
| 1678 |
| 1679 StringConstant get _constant => super._constant; |
| 1680 |
| 1681 bool get hasReflectee => true; |
| 1682 |
| 1683 get reflectee => _constant.value.slowToString(); |
| 1684 } |
| 1685 |
| 1686 class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { |
| 1687 Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1688 NumConstant constant) |
| 1689 : super(mirrors, constant); |
| 1690 |
| 1691 NumConstant get _constant => super._constant; |
| 1692 |
| 1693 bool get hasReflectee => true; |
| 1694 |
| 1695 get reflectee => _constant.value; |
| 1696 } |
| 1697 |
| 1698 class Dart2JsListConstantMirror extends Dart2JsConstantMirror |
| 1699 implements ListInstanceMirror { |
| 1700 Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1701 ListConstant constant) |
| 1702 : super(mirrors, constant); |
| 1703 |
| 1704 ListConstant get _constant => super._constant; |
| 1705 |
| 1706 int get length => _constant.length; |
| 1707 |
| 1708 Future<InstanceMirror> operator[](int index) { |
| 1709 if (index < 0) throw new RangeError('Negative index'); |
| 1710 if (index >= _constant.length) throw new RangeError('Index out of bounds'); |
| 1711 return new Future<InstanceMirror>.immediate( |
| 1712 _convertConstantToInstanceMirror(mirrors, _constant.entries[index])); |
| 1713 } |
| 1714 } |
| 1715 |
| 1716 class Dart2JsMapConstantMirror extends Dart2JsConstantMirror |
| 1717 implements MapInstanceMirror { |
| 1718 List<String> _listCache; |
| 1719 |
| 1720 Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1721 MapConstant constant) |
| 1722 : super(mirrors, constant); |
| 1723 |
| 1724 MapConstant get _constant => super._constant; |
| 1725 |
| 1726 List<String> get _list { |
| 1727 if (_listCache == null) { |
| 1728 _listCache = new List<String>(_constant.keys.entries.length); |
| 1729 int index = 0; |
| 1730 for (StringConstant keyConstant in _constant.keys.entries) { |
| 1731 _listCache[index] = keyConstant.value.slowToString(); |
| 1732 index++; |
| 1733 } |
| 1734 } |
| 1735 return _listCache; |
| 1736 } |
| 1737 |
| 1738 int get length => _constant.length; |
| 1739 |
| 1740 Collection<String> get keys { |
| 1741 // TODO(johnniwinther): Return an unmodifiable list instead. |
| 1742 return new List<String>.from(_list); |
| 1743 } |
| 1744 |
| 1745 Future<InstanceMirror> operator[](String key) { |
| 1746 int index = _list.indexOf(key); |
| 1747 if (index == -1) return null; |
| 1748 return new Future<InstanceMirror>.immediate( |
| 1749 _convertConstantToInstanceMirror(mirrors, _constant.values[index])); |
| 1750 } |
| 1751 } |
| 1752 |
| 1753 class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror |
| 1754 implements TypeInstanceMirror { |
| 1755 |
| 1756 Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1757 TypeConstant constant) |
| 1758 : super(mirrors, constant); |
| 1759 |
| 1760 TypeConstant get _constant => super._constant; |
| 1761 |
| 1762 TypeMirror get representedType => _convertTypeToTypeMirror( |
| 1763 mirrors, _constant.representedType, mirrors.compiler.types.dynamicType); |
| 1764 } |
| 1765 |
| 1766 class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror { |
| 1767 Map<String,Constant> _fieldMapCache; |
| 1768 |
| 1769 Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrors, |
| 1770 ConstructedConstant constant) |
| 1771 : super(mirrors, constant); |
| 1772 |
| 1773 ConstructedConstant get _constant => super._constant; |
| 1774 |
| 1775 Map<String,Constant> get _fieldMap { |
| 1776 if (_fieldMapCache == null) { |
| 1777 _fieldMapCache = new LinkedHashMap<String,Constant>(); |
| 1778 if (identical(_constant.type.element.kind, ElementKind.CLASS)) { |
| 1779 var index = 0; |
| 1780 ClassElement element = _constant.type.element; |
| 1781 element.forEachInstanceField((_, Element field) { |
| 1782 String fieldName = field.name.slowToString(); |
| 1783 _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]); |
| 1784 index++; |
| 1785 }, includeBackendMembers: true, includeSuperMembers: true); |
| 1786 } |
| 1787 } |
| 1788 return _fieldMapCache; |
| 1789 } |
| 1790 |
| 1791 Future<InstanceMirror> getField(String fieldName) { |
| 1792 Constant fieldConstant = _fieldMap[fieldName]; |
| 1793 if (fieldConstant != null) { |
| 1794 return new Future<InstanceMirror>.immediate( |
| 1795 _convertConstantToInstanceMirror(mirrors, fieldConstant)); |
| 1796 } |
| 1797 return super.getField(fieldName); |
| 1798 } |
| 1799 } |
OLD | NEW |