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..c31c42a3b993405345b4bf2511b9fe38406a225e 100644 |
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart |
@@ -113,6 +113,32 @@ 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) { |
+ // TODO(johnniwinther): Introduce a special ClassMirror for the null type? |
ahe
2012/12/19 15:44:03
Why? null is an instance of Null.
Johnni Winther
2012/12/20 11:30:35
Null is currently an internal class in js_helper,
|
+ return new Dart2JsNullConstantMirror(mirrors, constant); |
+ } else if (constant is ConstructedConstant) { |
+ return new Dart2JsConstructedConstantMirror(mirrors, constant); |
+ } |
+ throw new ArgumentError( |
ahe
2012/12/19 15:44:03
This is an internal error as _convertConstantToIns
Johnni Winther
2012/12/20 11:30:35
Changed to InternalError (+ some more places).
|
+ "Unexpected constant $constant"); |
+} |
+ |
class Dart2JsMethodKind { |
static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular"); |
static const Dart2JsMethodKind GENERATIVE = |
@@ -457,6 +483,15 @@ abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { |
String toString() => _element.toString(); |
int get hashCode => qualifiedName.hashCode; |
+ |
+ List<InstanceMirror> get metadata { |
+ var list = <InstanceMirror>[]; |
+ for (MetadataAnnotation metadata in _element.metadata) { |
+ metadata.ensureResolved(mirrors.compiler); |
+ list.add(_convertConstantToInstanceMirror(mirrors, metadata.value)); |
+ } |
+ return list; |
+ } |
} |
abstract class Dart2JsProxyMirror extends Dart2JsDeclarationMirror { |
@@ -649,6 +684,8 @@ class Dart2JsLibraryMirror extends Dart2JsContainerMirror |
} |
return new Dart2JsSourceLocation(script, span); |
} |
+ |
+ |
ahe
2012/12/19 15:44:03
Remove extra lines.
Johnni Winther
2012/12/20 11:30:35
Done.
|
} |
class Dart2JsSourceLocation implements SourceLocation { |
@@ -1131,6 +1168,16 @@ 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 { |
ahe
2012/12/19 15:44:03
My personal opinion on style: I don't like getters
Johnni Winther
2012/12/20 11:30:35
I don't either. Currently dart2js_mirror generally
Johnni Winther
2012/12/20 11:30:35
I don't either. Currently dart2js_mirror generally
|
+ var list = <InstanceMirror>[]; |
+ for (MetadataAnnotation metadata in _type.element.metadata) { |
+ metadata.ensureResolved(mirrors.compiler); |
+ list.add(_convertConstantToInstanceMirror(mirrors, metadata.value)); |
+ } |
+ return list; |
+ } |
} |
class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror |
@@ -1565,3 +1612,177 @@ class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror { |
} |
} |
} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Mirrors on constant values used for metadata. |
ahe
2012/12/19 15:44:03
Section comments don't work. A separate file or l
Johnni Winther
2012/12/20 11:30:35
Will do a split into multiple files at some point.
|
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+class Dart2JsConstantMirror extends InstanceMirror { |
+ final Dart2JsMirrorSystem mirrors; |
ahe
2012/12/19 15:44:03
If you store the type in a final, you don't need m
Johnni Winther
2012/12/20 11:30:35
It is required by the implemented Mirror interface
ahe
2013/01/03 12:03:05
The Mirror interface needs to be changed, then. A
Johnni Winther
2013/01/04 09:14:39
Added a TODO.
gbracha
2013/01/04 19:34:30
This is interesting collateral damage from the cha
|
+ final Constant _constant; |
+ |
+ Dart2JsConstantMirror(this.mirrors, this._constant); |
+ |
+ ClassMirror get type => new Dart2JsClassMirror( |
ahe
2012/12/19 15:44:03
If it doesn't fit on one line, my personal prefere
Johnni Winther
2012/12/20 11:30:35
Changed to { }
|
+ 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) { |
+ throw new NoSuchMethodError(this, fieldName, [], null); |
ahe
2012/12/19 15:44:03
Why are you throwing NoSuchMethod?
Johnni Winther
2012/12/20 11:30:35
Changed to UnsupportedError and added a TODO. I'm
|
+ } |
+} |
+ |
+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) |
ahe
2012/12/19 15:44:03
Indentation.
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ : 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'); |
+ var completer = new Completer<InstanceMirror>(); |
ahe
2012/12/19 15:44:03
return new Future.immediate(_convertConstantToInst
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ completer.complete( |
+ _convertConstantToInstanceMirror(mirrors, _constant.entries[index])); |
+ return completer.future; |
+ } |
+} |
+ |
+class Dart2JsMapConstantMirror extends Dart2JsConstantMirror |
+ implements MapInstanceMirror { |
+ List<String> _list; |
+ |
+ Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrors, |
+ MapConstant constant) |
+ : super(mirrors, constant); |
+ |
+ MapConstant get _constant => super._constant; |
+ |
+ void _ensureKeyList() { |
+ if (_list == null) { |
+ _list = new List<String>(); |
ahe
2012/12/19 15:44:03
Could this be a fixed-size list?
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ for (StringConstant keyConstant in _constant.keys.entries) { |
+ _list.add(keyConstant.value.slowToString()); |
+ } |
+ } |
+ } |
+ |
+ int get length => _constant.length; |
+ |
+ Collection<String> get keys { |
+ _ensureKeyList(); |
+ // TODO(johnniwinther): Return an unmodifiable list. |
+ return _list; |
ahe
2012/12/19 15:44:03
return new List<String>.from(_list)
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ } |
+ |
+ Future<InstanceMirror> operator[](String key) { |
+ _ensureKeyList(); |
+ int index = _list.indexOf(key); |
ahe
2012/12/19 15:44:03
How about using "keys" instead. Then you don't ne
Johnni Winther
2012/12/20 11:30:35
I don't want to copy the keys list as is now done
ahe
2013/01/03 12:23:02
Sounds like you need a todo for updating this code
Johnni Winther
2013/01/04 09:14:39
Changed to _ensureKeyList to _getKeyList which ret
|
+ if (index == -1) return null; |
+ var completer = new Completer<InstanceMirror>(); |
ahe
2012/12/19 15:44:03
Future.immediate
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ completer.complete( |
+ _convertConstantToInstanceMirror(mirrors, _constant.values[index])); |
+ return completer.future; |
+ } |
+} |
+ |
+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); |
+ |
ahe
2012/12/19 15:44:03
Extra line.
Johnni Winther
2012/12/20 11:30:35
Done.
|
+} |
+ |
+class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror { |
+ |
+ Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrors, |
+ ConstructedConstant constant) |
+ : super(mirrors, constant); |
+ |
+ ConstructedConstant get _constant => super._constant; |
+ |
+ Future<InstanceMirror> getField(String fieldName) { |
+ if (identical(_constant.type.element.kind, ElementKind.CLASS)) { |
+ ClassElement element = _constant.type.element; |
+ var fieldConstant = null; |
+ var index = 0; |
+ element.forEachInstanceField((_, Element field) { |
+ if (field.name.slowToString() == fieldName) { |
+ fieldConstant = _constant.fields[index]; |
ahe
2012/12/19 15:44:03
You need to stop iterating when a match is found:
Johnni Winther
2012/12/20 11:30:35
Done.
Johnni Winther
2012/12/20 11:30:35
Changed to compute a field map instead.
|
+ } |
+ index++; |
+ }, includeBackendMembers: true, includeSuperMembers: true); |
+ if (fieldConstant != null) { |
+ var completer = new Completer<InstanceMirror>(); |
ahe
2012/12/19 15:44:03
Future.immediate.
Johnni Winther
2012/12/20 11:30:35
Done.
|
+ completer.complete( |
+ _convertConstantToInstanceMirror(mirrors, fieldConstant)); |
+ return completer.future; |
+ } |
+ } |
+ return super.getField(fieldName); |
+ } |
+ |
ahe
2012/12/19 15:44:03
Extra line.
Johnni Winther
2012/12/20 11:30:35
Done.
|
+} |