Index: sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2fc0e938c0ae5739ccf1c368da3e12b8b38c72a4 |
--- /dev/null |
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_instance_mirrors.dart |
@@ -0,0 +1,278 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+part of dart2js.mirrors; |
+ |
+abstract class ObjectMirrorMixin implements ObjectMirror { |
+ InstanceMirror getField(Symbol fieldName) { |
+ throw new UnsupportedError('ObjectMirror.getField unsupported.'); |
+ } |
+ |
+ InstanceMirror setField(Symbol fieldName, Object value) { |
+ throw new UnsupportedError('ObjectMirror.setField unsupported.'); |
+ } |
+ |
+ InstanceMirror invoke(Symbol memberName, |
+ List positionalArguments, |
+ [Map<Symbol, dynamic> namedArguments]) { |
+ throw new UnsupportedError('ObjectMirror.invoke unsupported.'); |
+ } |
+} |
+ |
+abstract class InstanceMirrorMixin implements InstanceMirror { |
+ |
+ bool get hasReflectee => false; |
+ |
+ get reflectee { |
+ throw new UnsupportedError('InstanceMirror.reflectee unsupported.'); |
+ } |
+ |
+ Function operator [](Symbol name) { |
+ throw new UnsupportedError('InstanceMirror.operator [] unsupported.'); |
+ } |
+ |
+ delegate(Invocation invocation) { |
+ throw new UnsupportedError('InstanceMirror.delegate unsupported'); |
+ } |
+} |
+ |
+InstanceMirror _convertConstantToInstanceMirror( |
+ Dart2JsMirrorSystem mirrorSystem, Constant constant) { |
+ if (constant is BoolConstant) { |
+ return new Dart2JsBoolConstantMirror(mirrorSystem, constant); |
+ } else if (constant is NumConstant) { |
+ return new Dart2JsNumConstantMirror(mirrorSystem, constant); |
+ } else if (constant is StringConstant) { |
+ return new Dart2JsStringConstantMirror(mirrorSystem, constant); |
+ } else if (constant is ListConstant) { |
+ return new Dart2JsListConstantMirror(mirrorSystem, constant); |
+ } else if (constant is MapConstant) { |
+ return new Dart2JsMapConstantMirror(mirrorSystem, constant); |
+ } else if (constant is TypeConstant) { |
+ return new Dart2JsTypeConstantMirror(mirrorSystem, constant); |
+ } else if (constant is FunctionConstant) { |
+ return new Dart2JsConstantMirror(mirrorSystem, constant); |
+ } else if (constant is NullConstant) { |
+ return new Dart2JsNullConstantMirror(mirrorSystem, constant); |
+ } else if (constant is ConstructedConstant) { |
+ return new Dart2JsConstructedConstantMirror(mirrorSystem, constant); |
+ } |
+ mirrorSystem.compiler.internalError("Unexpected constant $constant"); |
+} |
+ |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Mirrors on constant values used for metadata. |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+class Dart2JsConstantMirror extends Object |
+ with ObjectMirrorMixin, InstanceMirrorMixin |
+ implements InstanceMirror { |
+ final Dart2JsMirrorSystem mirrorSystem; |
+ final Constant _constant; |
+ |
+ Dart2JsConstantMirror(this.mirrorSystem, this._constant); |
+ |
+ // TODO(johnniwinther): Improve the quality of this method. |
+ String toString() => '$_constant'; |
+ |
+ ClassMirror get type { |
+ return mirrorSystem._getTypeDeclarationMirror( |
+ _constant.computeType(mirrorSystem.compiler).element); |
+ } |
+} |
+ |
+class Dart2JsNullConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ NullConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ NullConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => null; |
+} |
+ |
+class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ BoolConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrorSystem, |
+ bool value) |
+ : super(mirrorSystem, value ? new TrueConstant() : new FalseConstant()); |
+ |
+ BoolConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant is TrueConstant; |
+} |
+ |
+class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ StringConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrorSystem, |
+ String text) |
+ : super(mirrorSystem, new StringConstant(new DartString.literal(text))); |
+ |
+ StringConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant.value.slowToString(); |
+} |
+ |
+class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { |
+ Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ NumConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ NumConstant get _constant => super._constant; |
+ |
+ bool get hasReflectee => true; |
+ |
+ get reflectee => _constant.value; |
+} |
+ |
+class Dart2JsListConstantMirror extends Dart2JsConstantMirror |
+ implements ListInstanceMirror { |
+ Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ ListConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ ListConstant get _constant => super._constant; |
+ |
+ int get length => _constant.length; |
+ |
+ InstanceMirror getElement(int index) { |
+ if (index < 0) throw new RangeError('Negative index'); |
+ if (index >= _constant.length) throw new RangeError('Index out of bounds'); |
+ return _convertConstantToInstanceMirror(mirrorSystem, |
+ _constant.entries[index]); |
+ } |
+} |
+ |
+class Dart2JsMapConstantMirror extends Dart2JsConstantMirror |
+ implements MapInstanceMirror { |
+ List<String> _listCache; |
+ |
+ Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ MapConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ MapConstant get _constant => super._constant; |
+ |
+ List<String> get _list { |
+ if (_listCache == null) { |
+ _listCache = new List<String>(_constant.keys.entries.length); |
+ int index = 0; |
+ for (StringConstant keyConstant in _constant.keys.entries) { |
+ _listCache[index] = keyConstant.value.slowToString(); |
+ index++; |
+ } |
+ _listCache = new UnmodifiableListView<String>(_listCache); |
+ } |
+ return _listCache; |
+ } |
+ |
+ int get length => _constant.length; |
+ |
+ Iterable<String> get keys { |
+ return _list; |
+ } |
+ |
+ InstanceMirror getValue(String key) { |
+ int index = _list.indexOf(key); |
+ if (index == -1) return null; |
+ return _convertConstantToInstanceMirror(mirrorSystem, |
+ _constant.values[index]); |
+ } |
+} |
+ |
+class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror |
+ implements TypeInstanceMirror { |
+ |
+ Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ TypeConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ TypeConstant get _constant => super._constant; |
+ |
+ TypeMirror get representedType => |
+ mirrorSystem._convertTypeToTypeMirror(_constant.representedType); |
+} |
+ |
+class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror { |
+ Map<String,Constant> _fieldMapCache; |
+ |
+ Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrorSystem, |
+ ConstructedConstant constant) |
+ : super(mirrorSystem, constant); |
+ |
+ ConstructedConstant get _constant => super._constant; |
+ |
+ Map<String,Constant> get _fieldMap { |
+ if (_fieldMapCache == null) { |
+ _fieldMapCache = new Map<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; |
+ _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]); |
+ index++; |
+ }, includeSuperAndInjectedMembers: true); |
+ } |
+ } |
+ return _fieldMapCache; |
+ } |
+ |
+ InstanceMirror getField(Symbol fieldName) { |
+ Constant fieldConstant = _fieldMap[MirrorSystem.getName(fieldName)]; |
+ if (fieldConstant != null) { |
+ return _convertConstantToInstanceMirror(mirrorSystem, fieldConstant); |
+ } |
+ return super.getField(fieldName); |
+ } |
+} |
+ |
+class Dart2JsCommentInstanceMirror extends Object |
+ with ObjectMirrorMixin, InstanceMirrorMixin |
+ implements CommentInstanceMirror { |
+ final Dart2JsMirrorSystem mirrorSystem; |
+ final String text; |
+ String _trimmedText; |
+ |
+ Dart2JsCommentInstanceMirror(this.mirrorSystem, this.text); |
+ |
+ ClassMirror get type { |
+ return mirrorSystem._getTypeDeclarationMirror( |
+ mirrorSystem.compiler.documentClass); |
+ } |
+ |
+ bool get isDocComment => text.startsWith('/**') || text.startsWith('///'); |
+ |
+ String get trimmedText { |
+ if (_trimmedText == null) { |
+ _trimmedText = stripComment(text); |
+ } |
+ return _trimmedText; |
+ } |
+ |
+ InstanceMirror getField(Symbol fieldName) { |
+ if (fieldName == #isDocComment) { |
+ return new Dart2JsBoolConstantMirror.fromBool(mirrorSystem, isDocComment); |
+ } else if (fieldName == #text) { |
+ return new Dart2JsStringConstantMirror.fromString(mirrorSystem, text); |
+ } else if (fieldName == #trimmedText) { |
+ return new Dart2JsStringConstantMirror.fromString(mirrorSystem, |
+ trimmedText); |
+ } |
+ super.getField(fieldName); |
+ } |
+} |