OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 part of dart2js.mirrors; | |
6 | |
7 abstract class ObjectMirrorMixin implements ObjectMirror { | |
8 InstanceMirror getField(Symbol fieldName) { | |
9 throw new UnsupportedError('ObjectMirror.getField unsupported.'); | |
10 } | |
11 | |
12 InstanceMirror setField(Symbol fieldName, Object value) { | |
13 throw new UnsupportedError('ObjectMirror.setField unsupported.'); | |
14 } | |
15 | |
16 InstanceMirror invoke(Symbol memberName, | |
17 List positionalArguments, | |
18 [Map<Symbol, dynamic> namedArguments]) { | |
19 throw new UnsupportedError('ObjectMirror.invoke unsupported.'); | |
20 } | |
21 } | |
22 | |
23 abstract class InstanceMirrorMixin implements InstanceMirror { | |
24 bool get hasReflectee => false; | |
25 | |
26 get reflectee { | |
27 throw new UnsupportedError('InstanceMirror.reflectee unsupported.'); | |
28 } | |
29 | |
30 delegate(Invocation invocation) { | |
31 throw new UnsupportedError('InstanceMirror.delegate unsupported'); | |
32 } | |
33 } | |
34 | |
35 InstanceMirror _convertConstantToInstanceMirror( | |
36 Dart2JsMirrorSystem mirrorSystem, | |
37 ConstantExpression constant, | |
38 ConstantValue value) { | |
39 | |
40 if (value.isBool) { | |
41 return new Dart2JsBoolConstantMirror(mirrorSystem, constant, value); | |
42 } else if (value.isNum) { | |
43 return new Dart2JsNumConstantMirror(mirrorSystem, constant, value); | |
44 } else if (value.isString) { | |
45 return new Dart2JsStringConstantMirror(mirrorSystem, constant, value); | |
46 } else if (value.isList) { | |
47 return new Dart2JsListConstantMirror(mirrorSystem, constant, value); | |
48 } else if (value.isMap) { | |
49 return new Dart2JsMapConstantMirror(mirrorSystem, constant, value); | |
50 } else if (value.isType) { | |
51 return new Dart2JsTypeConstantMirror(mirrorSystem, constant, value); | |
52 } else if (value.isFunction) { | |
53 return new Dart2JsConstantMirror(mirrorSystem, constant, value); | |
54 } else if (value.isNull) { | |
55 return new Dart2JsNullConstantMirror(mirrorSystem, constant, value); | |
56 } else if (value.isConstructedObject) { | |
57 return new Dart2JsConstructedConstantMirror(mirrorSystem, constant, value); | |
58 } | |
59 mirrorSystem.compiler.internalError(NO_LOCATION_SPANNABLE, | |
60 "Unexpected constant value $value"); | |
61 return null; | |
62 } | |
63 | |
64 | |
65 //////////////////////////////////////////////////////////////////////////////// | |
66 // Mirrors on constant values used for metadata. | |
67 //////////////////////////////////////////////////////////////////////////////// | |
68 | |
69 class Dart2JsConstantMirror extends Object | |
70 with ObjectMirrorMixin, InstanceMirrorMixin { | |
71 final Dart2JsMirrorSystem mirrorSystem; | |
72 final ConstantExpression _constant; | |
73 final ConstantValue _value; | |
74 | |
75 Dart2JsConstantMirror(this.mirrorSystem, this._constant, this._value); | |
76 | |
77 String toString() { | |
78 if (_constant != null) { | |
79 return _constant.getText(); | |
80 } else { | |
81 return _value.unparse(); | |
82 } | |
83 } | |
84 | |
85 ClassMirror get type { | |
86 return mirrorSystem._getTypeDeclarationMirror( | |
87 _value.computeType(mirrorSystem.compiler).element); | |
88 } | |
89 | |
90 int get hashCode => 13 * _constant.hashCode; | |
91 | |
92 bool operator ==(var other) { | |
93 if (other is! Dart2JsConstantMirror) return false; | |
94 return _value == other._value; | |
95 } | |
96 } | |
97 | |
98 class Dart2JsNullConstantMirror extends Dart2JsConstantMirror { | |
99 Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
100 ConstantExpression constant, | |
101 NullConstantValue value) | |
102 : super(mirrorSystem, constant, value); | |
103 | |
104 NullConstantValue get _value => super._value; | |
105 | |
106 bool get hasReflectee => true; | |
107 | |
108 get reflectee => null; | |
109 } | |
110 | |
111 class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { | |
112 Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
113 ConstantExpression constant, | |
114 BoolConstantValue value) | |
115 : super(mirrorSystem, constant, value); | |
116 | |
117 Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrorSystem, | |
118 bool value) | |
119 : super(mirrorSystem, null, | |
120 value ? new TrueConstantValue() : new FalseConstantValue()); | |
121 | |
122 BoolConstantValue get _value => super._value; | |
123 | |
124 bool get hasReflectee => true; | |
125 | |
126 get reflectee => _value is TrueConstantValue; | |
127 } | |
128 | |
129 class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { | |
130 Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
131 ConstantExpression constant, | |
132 StringConstantValue value) | |
133 : super(mirrorSystem, constant, value); | |
134 | |
135 Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrorSystem, | |
136 String text) | |
137 : super(mirrorSystem, null, | |
138 new StringConstantValue(new DartString.literal(text))); | |
139 | |
140 StringConstantValue get _value => super._value; | |
141 | |
142 bool get hasReflectee => true; | |
143 | |
144 get reflectee => _value.primitiveValue.slowToString(); | |
145 } | |
146 | |
147 class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { | |
148 Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
149 ConstantExpression constant, | |
150 NumConstantValue value) | |
151 : super(mirrorSystem, constant, value); | |
152 | |
153 NumConstantValue get _value => super._value; | |
154 | |
155 bool get hasReflectee => true; | |
156 | |
157 get reflectee => _value.primitiveValue; | |
158 } | |
159 | |
160 class Dart2JsListConstantMirror extends Dart2JsConstantMirror | |
161 implements ListInstanceMirror { | |
162 Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
163 ConstantExpression constant, | |
164 ListConstantValue value) | |
165 : super(mirrorSystem, constant, value); | |
166 | |
167 ListConstantValue get _value => super._value; | |
168 | |
169 int get length => _value.length; | |
170 | |
171 InstanceMirror getElement(int index) { | |
172 if (index < 0) throw new RangeError('Negative index'); | |
173 if (index >= _value.length) throw new RangeError('Index out of bounds'); | |
174 return _convertConstantToInstanceMirror( | |
175 mirrorSystem, null, _value.entries[index]); | |
176 } | |
177 } | |
178 | |
179 class Dart2JsMapConstantMirror extends Dart2JsConstantMirror | |
180 implements MapInstanceMirror { | |
181 List<String> _listCache; | |
182 | |
183 Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
184 ConstantExpression constant, | |
185 MapConstantValue value) | |
186 : super(mirrorSystem, constant, value); | |
187 | |
188 MapConstantValue get _value => super._value; | |
189 | |
190 List<String> get _list { | |
191 if (_listCache == null) { | |
192 _listCache = new List<String>(_value.length); | |
193 int index = 0; | |
194 for (StringConstantValue keyConstant in _value.keys) { | |
195 _listCache[index] = keyConstant.primitiveValue.slowToString(); | |
196 index++; | |
197 } | |
198 _listCache = new UnmodifiableListView<String>(_listCache); | |
199 } | |
200 return _listCache; | |
201 } | |
202 | |
203 int get length => _value.length; | |
204 | |
205 Iterable<String> get keys { | |
206 return _list; | |
207 } | |
208 | |
209 InstanceMirror getValue(String key) { | |
210 int index = _list.indexOf(key); | |
211 if (index == -1) return null; | |
212 return _convertConstantToInstanceMirror( | |
213 mirrorSystem, null, _value.values[index]); | |
214 } | |
215 } | |
216 | |
217 class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror | |
218 implements TypeInstanceMirror { | |
219 | |
220 Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
221 ConstantExpression constant, | |
222 TypeConstantValue value) | |
223 : super(mirrorSystem, constant, value); | |
224 | |
225 TypeConstantValue get _value => super._value; | |
226 | |
227 TypeMirror get representedType => | |
228 mirrorSystem._convertTypeToTypeMirror(_value.representedType); | |
229 } | |
230 | |
231 class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror { | |
232 Map<String,ConstantValue> _fieldMapCache; | |
233 | |
234 Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrorSystem, | |
235 ConstantExpression constant, | |
236 ConstructedConstantValue value) | |
237 : super(mirrorSystem, constant, value); | |
238 | |
239 ConstructedConstantValue get _value => super._value; | |
240 | |
241 Map<String,ConstantValue> get _fieldMap { | |
242 if (_fieldMapCache == null) { | |
243 _fieldMapCache = new Map<String,ConstantValue>(); | |
244 if (identical(_value.type.element.kind, ElementKind.CLASS)) { | |
245 var index = 0; | |
246 ClassElement element = _value.type.element; | |
247 element.forEachInstanceField((_, Element field) { | |
248 String fieldName = field.name; | |
249 _fieldMapCache.putIfAbsent(fieldName, () => _value.fields[index]); | |
250 index++; | |
251 }, includeSuperAndInjectedMembers: true); | |
252 } | |
253 } | |
254 return _fieldMapCache; | |
255 } | |
256 | |
257 InstanceMirror getField(Symbol fieldName) { | |
258 String name = MirrorSystem.getName(fieldName); | |
259 ConstantValue fieldConstant = _fieldMap[name]; | |
260 if (fieldConstant != null) { | |
261 return _convertConstantToInstanceMirror( | |
262 mirrorSystem, null, fieldConstant); | |
263 } | |
264 return super.getField(fieldName); | |
265 } | |
266 } | |
267 | |
268 class Dart2JsCommentInstanceMirror extends Object | |
269 with ObjectMirrorMixin, InstanceMirrorMixin | |
270 implements CommentInstanceMirror { | |
271 final Dart2JsMirrorSystem mirrorSystem; | |
272 final String text; | |
273 String _trimmedText; | |
274 | |
275 Dart2JsCommentInstanceMirror(this.mirrorSystem, this.text); | |
276 | |
277 ClassMirror get type { | |
278 return mirrorSystem._getTypeDeclarationMirror( | |
279 mirrorSystem.compiler.documentClass); | |
280 } | |
281 | |
282 bool get isDocComment => text.startsWith('/**') || text.startsWith('///'); | |
283 | |
284 String get trimmedText { | |
285 if (_trimmedText == null) { | |
286 _trimmedText = stripComment(text); | |
287 } | |
288 return _trimmedText; | |
289 } | |
290 | |
291 InstanceMirror getField(Symbol fieldName) { | |
292 if (fieldName == #isDocComment) { | |
293 return new Dart2JsBoolConstantMirror.fromBool(mirrorSystem, isDocComment); | |
294 } else if (fieldName == #text) { | |
295 return new Dart2JsStringConstantMirror.fromString(mirrorSystem, text); | |
296 } else if (fieldName == #trimmedText) { | |
297 return new Dart2JsStringConstantMirror.fromString(mirrorSystem, | |
298 trimmedText); | |
299 } | |
300 return super.getField(fieldName); | |
301 } | |
302 } | |
OLD | NEW |