OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library mirrors_util; | 5 library mirrors_util; |
6 | 6 |
7 import 'dart:collection' show Queue, IterableBase; | 7 import 'dart:collection' show Queue, IterableBase; |
8 | 8 |
9 // TODO(rnystrom): Use "package:" URL (#4968). | 9 // TODO(rnystrom): Use "package:" URL (#4968). |
10 import 'mirrors.dart'; | 10 import 'mirrors.dart'; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 _current = object; | 165 _current = object; |
166 object = null; | 166 object = null; |
167 return true; | 167 return true; |
168 } else { | 168 } else { |
169 _current = push(queue.removeFirst()); | 169 _current = push(queue.removeFirst()); |
170 return true; | 170 return true; |
171 } | 171 } |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 bool isMixinApplication(ClassMirror mirror) { | |
176 return mirror != null && mirror.mixin != mirror; | |
177 } | |
178 | |
179 /** | |
180 * Returns the superclass of [cls] skipping unnamed mixin applications. | |
181 * | |
182 * For instance, for all of the following definitions this method returns [:B:]. | |
183 * | |
184 * class A extends B {} | |
185 * class A extends B with C1, C2 {} | |
186 * class A extends B implements D1, D2 {} | |
187 * class A extends B with C1, C2 implements D1, D2 {} | |
188 * typedef A = B with C1, C2; | |
189 * typedef A = abstract B with C1, C2 implements D1, D2; | |
190 */ | |
191 ClassMirror getExtends(ClassMirror cls) { | |
karlklose
2013/11/05 10:34:18
Change to 'getSuperclass'?
Johnni Winther
2013/11/05 11:20:47
Done.
| |
192 ClassMirror superclass = cls.superclass; | |
193 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { | |
194 superclass = superclass.superclass; | |
195 } | |
196 return superclass; | |
197 } | |
198 | |
199 /** | |
200 * Returns the mixins directly applied to [cls]. | |
201 * | |
202 * For instance, for all of the following definitions this method returns | |
203 * [:C1, C2:]. | |
204 * | |
205 * class A extends B with C1, C2 {} | |
206 * class A extends B with C1, C2 implements D1, D2 {} | |
207 * typedef A = B with C1, C2; | |
208 * typedef A = abstract B with C1, C2 implements D1, D2; | |
209 */ | |
210 Iterable<ClassMirror> getWith(ClassMirror cls) { | |
karlklose
2013/11/05 10:34:18
Change to 'getAppliedMixins'?
Johnni Winther
2013/11/05 11:20:47
Done.
| |
211 List<ClassMirror> mixins = <ClassMirror>[]; | |
212 ClassMirror superclass = cls.superclass; | |
213 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { | |
214 mixins.add(superclass.mixin); | |
215 superclass = superclass.superclass; | |
216 } | |
217 if (mixins.length > 1) { | |
218 mixins = new List<ClassMirror>.from(mixins.reversed); | |
219 } | |
220 if (isMixinApplication(cls)) { | |
221 mixins.add(cls.mixin); | |
222 } | |
223 return mixins; | |
224 } | |
225 | |
226 /** | |
227 * Returns the superinterfaces directly and explicitly implemented by [cls]. | |
228 * | |
229 * For instance, for all of the following definitions this method returns | |
230 * [:D1, D2:]. | |
231 * | |
232 * class A extends B implements D1, D2 {} | |
233 * class A extends B with C1, C2 implements D1, D2 {} | |
234 * typedef A = abstract B with C1, C2 implements D1, D2; | |
235 */ | |
236 Iterable<ClassMirror> getImplements(ClassMirror cls) { | |
karlklose
2013/11/05 10:34:18
Change to 'getExplicitInterfaces' or something sim
Johnni Winther
2013/11/05 11:20:47
Done.
| |
237 if (isMixinApplication(cls)) { | |
238 bool first = true; | |
239 ClassMirror mixin = cls.mixin; | |
240 bool filter(ClassMirror superinterface) { | |
241 if (first && superinterface == mixin) { | |
242 first = false; | |
243 return false; | |
244 } | |
245 return true; | |
246 } | |
247 return cls.superinterfaces.where(filter); | |
248 } | |
249 return cls.superinterfaces; | |
250 } | |
251 | |
175 final RegExp _singleLineCommentStart = new RegExp(r'^///? ?(.*)'); | 252 final RegExp _singleLineCommentStart = new RegExp(r'^///? ?(.*)'); |
176 final RegExp _multiLineCommentStartEnd = | 253 final RegExp _multiLineCommentStartEnd = |
177 new RegExp(r'^/\*\*? ?([\s\S]*)\*/$', multiLine: true); | 254 new RegExp(r'^/\*\*? ?([\s\S]*)\*/$', multiLine: true); |
178 final RegExp _multiLineCommentLineStart = new RegExp(r'^[ \t]*\* ?(.*)'); | 255 final RegExp _multiLineCommentLineStart = new RegExp(r'^[ \t]*\* ?(.*)'); |
179 | 256 |
180 /** | 257 /** |
181 * Pulls the raw text out of a comment (i.e. removes the comment | 258 * Pulls the raw text out of a comment (i.e. removes the comment |
182 * characters). | 259 * characters). |
183 */ | 260 */ |
184 String stripComment(String comment) { | 261 String stripComment(String comment) { |
(...skipping 28 matching lines...) Expand all Loading... | |
213 } | 290 } |
214 return sb.toString(); | 291 return sb.toString(); |
215 } | 292 } |
216 throw new ArgumentError('Invalid comment $comment'); | 293 throw new ArgumentError('Invalid comment $comment'); |
217 } | 294 } |
218 | 295 |
219 /** | 296 /** |
220 * Looks up [name] in the scope [declaration]. | 297 * Looks up [name] in the scope [declaration]. |
221 * | 298 * |
222 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of | 299 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of |
223 * [declaration] and if unresolved 'a.b' is looked in the scope of | 300 * [declaration] and if unresolved 'a.b' is looked in the scope of |
224 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is | 301 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is |
225 * then looked up in the local scope of the previous result. | 302 * then looked up in the local scope of the previous result. |
226 * | 303 * |
227 * For instance, assumming that [:Iterable:] is imported into the scope of | 304 * For instance, assumming that [:Iterable:] is imported into the scope of |
228 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type | 305 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type |
229 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the | 306 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the |
230 * [:element:] parameter of the [:contains:] method on [:Iterable:]. | 307 * [:element:] parameter of the [:contains:] method on [:Iterable:]. |
231 */ | 308 */ |
232 DeclarationMirror lookupQualifiedInScope(DeclarationMirror declaration, | 309 DeclarationMirror lookupQualifiedInScope(DeclarationMirror declaration, |
233 String name) { | 310 String name) { |
234 // TODO(11653): Support lookup of constructors using the [:new Foo:] | 311 // TODO(11653): Support lookup of constructors using the [:new Foo:] |
235 // syntax. | 312 // syntax. |
236 int offset = 1; | 313 int offset = 1; |
237 List<String> parts = name.split('.'); | 314 List<String> parts = name.split('.'); |
238 DeclarationMirror result = declaration.lookupInScope(parts[0]); | 315 DeclarationMirror result = declaration.lookupInScope(parts[0]); |
239 if (result == null && parts.length > 1) { | 316 if (result == null && parts.length > 1) { |
240 // Try lookup of `prefix.id`. | 317 // Try lookup of `prefix.id`. |
241 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); | 318 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); |
242 offset = 2; | 319 offset = 2; |
243 } | 320 } |
244 if (result == null) return null; | 321 if (result == null) return null; |
245 while (result != null && offset < parts.length) { | 322 while (result != null && offset < parts.length) { |
246 result = _lookupLocal(result, parts[offset++]); | 323 result = _lookupLocal(result, parts[offset++]); |
(...skipping 15 matching lines...) Expand all Loading... | |
262 result = classMirror.typeVariables.firstWhere( | 339 result = classMirror.typeVariables.firstWhere( |
263 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null); | 340 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null); |
264 } else if (mirror is MethodMirror) { | 341 } else if (mirror is MethodMirror) { |
265 MethodMirror methodMirror = mirror; | 342 MethodMirror methodMirror = mirror; |
266 result = methodMirror.parameters.firstWhere( | 343 result = methodMirror.parameters.firstWhere( |
267 (ParameterMirror p) => p.simpleName == id, orElse: () => null); | 344 (ParameterMirror p) => p.simpleName == id, orElse: () => null); |
268 } | 345 } |
269 return result; | 346 return result; |
270 | 347 |
271 } | 348 } |
OLD | NEW |