Index: sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
index 398d64156277adf4d7c927c8c7e9e7cc5b6d0325..d3143e00c54f9454c9881bcd424f6ce3229ecf94 100644 |
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
@@ -79,7 +79,9 @@ Dart2JsTypeMirror _convertTypeToTypeMirror( |
// TODO(johnniwinther): We need a mirror on malformed types. |
return system.dynamicType; |
} |
- throw new ArgumentError("Unexpected type $type of kind ${type.kind}"); |
+ _diagnosticListener.internalError( |
+ "Unexpected type $type of kind ${type.kind}"); |
+ system.compiler.internalError("Unexpected type $type of kind ${type.kind}"); |
} |
Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( |
@@ -100,7 +102,7 @@ Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( |
} |
return members; |
} |
- throw new ArgumentError( |
+ library.mirrors.compiler.internalError( |
"Unexpected member type $element ${element.kind}"); |
} |
@@ -113,6 +115,30 @@ MethodMirror _convertElementMethodToMethodMirror(Dart2JsContainerMirror library, |
} |
} |
+InstanceMirror _convertConstantToInstanceMirror(Dart2JsMirrorSystem mirrors, |
+ Constant constant) { |
+ if (constant is BoolConstant) { |
+ return new Dart2JsBoolConstantMirror(mirrors, constant); |
+ } else if (constant is NumConstant) { |
+ return new Dart2JsNumConstantMirror(mirrors, constant); |
+ } else if (constant is StringConstant) { |
+ return new Dart2JsStringConstantMirror(mirrors, constant); |
+ } else if (constant is ListConstant) { |
+ return new Dart2JsListConstantMirror(mirrors, constant); |
+ } else if (constant is MapConstant) { |
+ return new Dart2JsMapConstantMirror(mirrors, constant); |
+ } else if (constant is TypeConstant) { |
+ return new Dart2JsTypeConstantMirror(mirrors, constant); |
+ } else if (constant is FunctionConstant) { |
+ return new Dart2JsConstantMirror(mirrors, constant); |
+ } else if (constant is NullConstant) { |
+ return new Dart2JsNullConstantMirror(mirrors, constant); |
+ } else if (constant is ConstructedConstant) { |
+ return new Dart2JsConstructedConstantMirror(mirrors, constant); |
+ } |
+ mirrors.compiler.internalError("Unexpected constant $constant"); |
+} |
+ |
class Dart2JsMethodKind { |
static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular"); |
static const Dart2JsMethodKind GENERATIVE = |
@@ -440,6 +466,7 @@ abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror |
abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { |
final Dart2JsMirrorSystem mirrors; |
final Element _element; |
+ List<InstanceMirror> _metadata; |
Dart2JsElementMirror(this.mirrors, this._element) { |
assert (mirrors != null); |
@@ -457,6 +484,19 @@ abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { |
String toString() => _element.toString(); |
int get hashCode => qualifiedName.hashCode; |
+ |
+ List<InstanceMirror> get metadata { |
+ if (_metadata == null) { |
+ _metadata = <InstanceMirror>[]; |
+ for (MetadataAnnotation metadata in _element.metadata) { |
+ metadata.ensureResolved(mirrors.compiler); |
+ _metadata.add( |
+ _convertConstantToInstanceMirror(mirrors, metadata.value)); |
+ } |
+ } |
+ // TODO(johnniwinther): Return an unmodifiable list instead. |
+ return new List<InstanceMirror>.from(_metadata); |
+ } |
} |
abstract class Dart2JsProxyMirror extends Dart2JsDeclarationMirror { |
@@ -1086,6 +1126,7 @@ class Dart2JsTypeVariableMirror extends Dart2JsTypeElementMirror |
abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror |
implements Dart2JsTypeMirror { |
final DartType _type; |
+ List<InstanceMirror> _metadata; |
Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, this._type) |
: super(system); |
@@ -1131,6 +1172,20 @@ abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror |
Map<String, VariableMirror> get variables => const <String, VariableMirror>{}; |
ClassMirror get defaultFactory => null; |
+ |
+ // TODO(johnniwinther): Should a type show the metadata of its declaration? |
+ List<InstanceMirror> get metadata { |
+ if (_metadata == null) { |
+ var _metadata = <InstanceMirror>[]; |
+ for (MetadataAnnotation metadata in _type.element.metadata) { |
+ metadata.ensureResolved(mirrors.compiler); |
+ _metadata.add( |
+ _convertConstantToInstanceMirror(mirrors, metadata.value)); |
+ } |
+ } |
+ // TODO(johnniwinther): Return an unmodifiable list instead. |
+ return new List<InstanceMirror>.from(_metadata); |
+ } |
} |
class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror |
@@ -1565,3 +1620,180 @@ class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror { |
} |
} |
} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Mirrors on constant values used for metadata. |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+class Dart2JsConstantMirror extends InstanceMirror { |
+ final Dart2JsMirrorSystem mirrors; |
+ final Constant _constant; |
+ |
+ Dart2JsConstantMirror(this.mirrors, this._constant); |
+ |
+ ClassMirror get type { |
+ return new Dart2JsClassMirror(mirrors, |
+ _constant.computeType(mirrors.compiler).element); |
+ } |
+ |
+ bool get hasReflectee => false; |
+ |
+ get reflectee { |
+ // TODO(johnniwinther): Which exception/error should be thrown here? |
+ throw new UnsupportedError('InstanceMirror does not have a reflectee'); |
+ } |
+ |
+ Future<InstanceMirror> getField(String fieldName) { |
+ // TODO(johnniwinther): Which exception/error should be thrown here? |
+ throw new UnsupportedError('InstanceMirror does not have a reflectee'); |
+ } |
+} |
+ |
+class Dart2JsNullConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrors, NullConstant constant) |
+ : super(mirrors, constant); |
+ |
+ NullConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => null; |
+} |
+ |
+class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant) |
+ : super(mirrors, constant); |
+ |
+ BoolConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant is TrueConstant; |
+} |
+ |
+class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors, |
+ StringConstant constant) |
+ : super(mirrors, constant); |
+ |
+ StringConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant.value.slowToString(); |
+} |
+ |
+class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors, |
+ NumConstant constant) |
+ : super(mirrors, constant); |
+ |
+ NumConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant.value; |
+} |
+ |
+class Dart2JsListConstantMirror extends Dart2JsConstantMirror |
+ implements ListInstanceMirror { |
+ Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrors, |
+ ListConstant constant) |
+ : super(mirrors, constant); |
+ |
+ ListConstant get _constant => super._constant; |
+ |
+ int get length => _constant.length; |
+ |
+ Future<InstanceMirror> operator[](int index) { |
+ if (index < 0) throw new RangeError('Negative index'); |
+ if (index >= _constant.length) throw new RangeError('Index out of bounds'); |
+ return new Future<InstanceMirror>.immediate( |
+ _convertConstantToInstanceMirror(mirrors, _constant.entries[index])); |
+ } |
+} |
+ |
+class Dart2JsMapConstantMirror extends Dart2JsConstantMirror |
+ implements MapInstanceMirror { |
+ List<String> _list; |
+ |
+ Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrors, |
+ MapConstant constant) |
+ : super(mirrors, constant); |
+ |
+ MapConstant get _constant => super._constant; |
+ |
+ List<String> _getKeyList() { |
ahe
2013/01/04 09:20:44
I'm still not feeling the love for this. This feel
Johnni Winther
2013/01/04 09:52:06
Done.
|
+ if (_list == null) { |
+ _list = new List<String>(_constant.keys.entries.length); |
+ int index = 0; |
+ for (StringConstant keyConstant in _constant.keys.entries) { |
+ _list[index] = keyConstant.value.slowToString(); |
+ index++; |
+ } |
+ } |
+ return _list; |
+ } |
+ |
+ int get length => _constant.length; |
+ |
+ Collection<String> get keys { |
+ // TODO(johnniwinther): Return an unmodifiable list instead. |
+ return new List<String>.from(_getKeyList()); |
+ } |
+ |
+ Future<InstanceMirror> operator[](String key) { |
+ int index = _getKeyList().indexOf(key); |
+ if (index == -1) return null; |
+ return new Future<InstanceMirror>.immediate( |
+ _convertConstantToInstanceMirror(mirrors, _constant.values[index])); |
+ } |
+} |
+ |
+class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror |
+ implements TypeInstanceMirror { |
+ |
+ Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrors, |
+ TypeConstant constant) |
+ : super(mirrors, constant); |
+ |
+ TypeConstant get _constant => super._constant; |
+ |
+ TypeMirror get representedType => _convertTypeToTypeMirror( |
+ mirrors, _constant.representedType, mirrors.compiler.types.dynamicType); |
+} |
+ |
+class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror { |
+ Map<String,Constant> _fieldMap; |
+ |
+ Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrors, |
+ ConstructedConstant constant) |
+ : super(mirrors, constant); |
+ |
+ ConstructedConstant get _constant => super._constant; |
+ |
+ Map<String,Constant> _getFieldMap() { |
+ if (_fieldMap == null) { |
+ _fieldMap = new LinkedHashMap<String,Constant>(); |
+ if (identical(_constant.type.element.kind, ElementKind.CLASS)) { |
+ var index = 0; |
+ ClassElement element = _constant.type.element; |
+ element.forEachInstanceField((_, Element field) { |
+ String fieldName = field.name.slowToString(); |
+ _fieldMap.putIfAbsent(fieldName, () => _constant.fields[index]); |
+ index++; |
+ }, includeBackendMembers: true, includeSuperMembers: true); |
+ } |
+ } |
+ return _fieldMap; |
+ } |
+ |
+ Future<InstanceMirror> getField(String fieldName) { |
+ Constant fieldConstant = _getFieldMap()[fieldName]; |
+ if (fieldConstant != null) { |
+ return new Future<InstanceMirror>.immediate( |
+ _convertConstantToInstanceMirror(mirrors, fieldConstant)); |
+ } |
+ return super.getField(fieldName); |
+ } |
+} |