|
1 | 1 | library reflection.reflection_capabilities; |
2 | 2 |
|
3 | | -import 'dart:mirrors'; |
4 | | - |
5 | | -import 'package:angular2/src/core/linker/interfaces.dart'; |
6 | 3 | import 'package:angular2/src/facade/lang.dart'; |
7 | | - |
8 | | -import 'platform_reflection_capabilities.dart'; |
9 | 4 | import 'types.dart'; |
| 5 | +import 'dart:mirrors'; |
| 6 | +import 'platform_reflection_capabilities.dart'; |
10 | 7 |
|
11 | 8 | var DOT_REGEX = new RegExp('\\.'); |
12 | 9 |
|
@@ -275,9 +272,7 @@ class ReflectionCapabilities implements PlatformReflectionCapabilities { |
275 | 272 | } |
276 | 273 |
|
277 | 274 | List interfaces(type) { |
278 | | - final clazz = reflectType(type); |
279 | | - _assertDeclaresLifecycleHooks(clazz); |
280 | | - return _interfacesFromMirror(clazz); |
| 275 | + return _interfacesFromMirror(reflectType(type)); |
281 | 276 | } |
282 | 277 |
|
283 | 278 | List _interfacesFromMirror(classMirror) { |
@@ -329,103 +324,3 @@ class ReflectionCapabilities implements PlatformReflectionCapabilities { |
329 | 324 | return '${(reflectClass(type).owner as LibraryMirror).uri}'; |
330 | 325 | } |
331 | 326 | } |
332 | | - |
333 | | -final _lifecycleHookMirrors = <ClassMirror>[ |
334 | | - reflectType(AfterContentChecked), |
335 | | - reflectType(AfterContentInit), |
336 | | - reflectType(AfterViewChecked), |
337 | | - reflectType(AfterViewInit), |
338 | | - reflectType(DoCheck), |
339 | | - reflectType(OnChanges), |
340 | | - reflectType(OnDestroy), |
341 | | - reflectType(OnInit), |
342 | | -]; |
343 | | - |
344 | | -/// Checks whether [clazz] implements lifecycle ifaces without declaring them. |
345 | | -/// |
346 | | -/// Due to Dart implementation details, lifecycle hooks are only called when a |
347 | | -/// class explicitly declares that it implements the associated interface. |
348 | | -/// See https://goo.gl/b07Kii for details. |
349 | | -void _assertDeclaresLifecycleHooks(ClassMirror clazz) { |
350 | | - final missingDeclarations = <ClassMirror>[]; |
351 | | - for (var iface in _lifecycleHookMirrors) { |
352 | | - if (!_checkDeclares(clazz, iface: iface) && |
353 | | - _checkImplements(clazz, iface: iface)) { |
354 | | - missingDeclarations.add(iface); |
355 | | - } |
356 | | - } |
357 | | - if (missingDeclarations.isNotEmpty) { |
358 | | - throw new MissingInterfaceError(clazz, missingDeclarations); |
359 | | - } |
360 | | -} |
361 | | - |
362 | | -/// Returns whether [clazz] declares that it implements [iface]. |
363 | | -/// |
364 | | -/// Returns `false` if [clazz] implements [iface] but does not declare it. |
365 | | -/// Returns `false` if [clazz]'s superclass declares that it |
366 | | -/// implements [iface]. |
367 | | -bool _checkDeclares(ClassMirror clazz, {ClassMirror iface: null}) { |
368 | | - if (iface == null) { |
369 | | - throw new ArgumentError.notNull('iface'); |
370 | | - } |
371 | | - return clazz.superinterfaces.contains(iface); |
372 | | -} |
373 | | - |
374 | | -/// Returns whether [clazz] implements [iface]. |
375 | | -/// |
376 | | -/// Returns `true` if [clazz] implements [iface] and does not declare it. |
377 | | -/// Returns `true` if [clazz]'s superclass implements [iface]. |
378 | | -/// |
379 | | -/// This is an approximation of a JavaScript feature check: |
380 | | -/// ```js |
381 | | -/// var matches = true; |
382 | | -/// for (var prop in iface) { |
383 | | -/// if (iface.hasOwnProperty(prop)) { |
384 | | -/// matches = matches && clazz.hasOwnProperty(prop); |
385 | | -/// } |
386 | | -/// } |
387 | | -/// return matches; |
388 | | -/// ``` |
389 | | -bool _checkImplements(ClassMirror clazz, {ClassMirror iface: null}) { |
390 | | - if (iface == null) { |
391 | | - throw new ArgumentError.notNull('iface'); |
392 | | - } |
393 | | - |
394 | | - var matches = true; |
395 | | - iface.declarations.forEach((symbol, declarationMirror) { |
396 | | - if (!matches) return; |
397 | | - if (declarationMirror.isConstructor || declarationMirror.isPrivate) return; |
398 | | - matches = clazz.declarations.keys.contains(symbol); |
399 | | - }); |
400 | | - if (!matches && clazz.superclass != null) { |
401 | | - matches = _checkImplements(clazz.superclass, iface: iface); |
402 | | - } |
403 | | - if (!matches && clazz.mixin != clazz) { |
404 | | - matches = _checkImplements(clazz.mixin, iface: iface); |
405 | | - } |
406 | | - |
407 | | - return matches; |
408 | | -} |
409 | | - |
410 | | -/// Error thrown when a class implements a lifecycle iface it does not declare. |
411 | | -class MissingInterfaceError extends Error { |
412 | | - final ClassMirror clazz; |
413 | | - final List<ClassMirror> missingDeclarations; |
414 | | - |
415 | | - MissingInterfaceError(this.clazz, this.missingDeclarations); |
416 | | - |
417 | | - @override |
418 | | - String toString() { |
419 | | - final buf = new StringBuffer(); |
420 | | - buf.write('${clazz.simpleName} implements '); |
421 | | - if (missingDeclarations.length == 1) { |
422 | | - buf.write('an interface but does not declare it: '); |
423 | | - } else { |
424 | | - buf.write('interfaces but does not declare them: '); |
425 | | - } |
426 | | - buf.write( |
427 | | - missingDeclarations.map((d) => d.simpleName.toString()).join(', ')); |
428 | | - buf.write('. See https://goo.gl/b07Kii for more info.'); |
429 | | - return buf.toString(); |
430 | | - } |
431 | | -} |
0 commit comments