Chromium Code Reviews| 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 |