Chromium Code Reviews| 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.
|
| +} |