fix(compiler): support lifecycle hooks in compiler_cli

This commit is contained in:
Tobias Bosch
2016-05-04 10:00:59 -07:00
parent bdce154282
commit 7150ace7c7
15 changed files with 143 additions and 102 deletions

View File

@ -75,7 +75,7 @@ export var LIFECYCLE_HOOKS_VALUES = [
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface OnChanges { ngOnChanges(changes: {[key: string]: SimpleChange}); }
export abstract class OnChanges { abstract ngOnChanges(changes: {[key: string]: SimpleChange}); }
/**
* Implement this interface to execute custom initialization logic after your directive's
@ -118,7 +118,7 @@ export interface OnChanges { ngOnChanges(changes: {[key: string]: SimpleChange})
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface OnInit { ngOnInit(); }
export abstract class OnInit { abstract ngOnInit(); }
/**
* Implement this interface to override the default change detection algorithm for your directive.
@ -185,7 +185,7 @@ export interface OnInit { ngOnInit(); }
* }
* ```
*/
export interface DoCheck { ngDoCheck(); }
export abstract class DoCheck { abstract ngDoCheck(); }
/**
* Implement this interface to get notified when your directive is destroyed.
@ -276,7 +276,7 @@ export interface DoCheck { ngDoCheck(); }
* every 50ms, until it reaches 0.
*
*/
export interface OnDestroy { ngOnDestroy(); }
export abstract class OnDestroy { abstract ngOnDestroy(); }
/**
* Implement this interface to get notified when your directive's content has been fully
@ -329,7 +329,7 @@ export interface OnDestroy { ngOnDestroy(); }
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface AfterContentInit { ngAfterContentInit(); }
export abstract class AfterContentInit { abstract ngAfterContentInit(); }
/**
* Implement this interface to get notified after every check of your directive's content.
@ -377,7 +377,7 @@ export interface AfterContentInit { ngAfterContentInit(); }
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface AfterContentChecked { ngAfterContentChecked(); }
export abstract class AfterContentChecked { abstract ngAfterContentChecked(); }
/**
* Implement this interface to get notified when your component's view has been fully initialized.
@ -424,7 +424,7 @@ export interface AfterContentChecked { ngAfterContentChecked(); }
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface AfterViewInit { ngAfterViewInit(); }
export abstract class AfterViewInit { abstract ngAfterViewInit(); }
/**
* Implement this interface to get notified after every check of your component's view.
@ -474,4 +474,4 @@ export interface AfterViewInit { ngAfterViewInit(); }
* bootstrap(App).catch(err => console.error(err));
* ```
*/
export interface AfterViewChecked { ngAfterViewChecked(); }
export abstract class AfterViewChecked { abstract ngAfterViewChecked(); }

View File

@ -5,6 +5,7 @@ export interface PlatformReflectionCapabilities {
isReflectionEnabled(): boolean;
factory(type: Type): Function;
interfaces(type: Type): any[];
hasLifecycleHook(type: any, lcInterface: /*Type*/ any, lcProperty: string): boolean;
parameters(type: any): any[][];
annotations(type: any): any[];
propMetadata(typeOrFunc: any): {[key: string]: any[]};

View File

@ -291,6 +291,11 @@ class ReflectionCapabilities implements PlatformReflectionCapabilities {
return name.endsWith("=") ? name.substring(0, name.length - 1) : name;
}
bool hasLifecycleHook(dynamic type, Type lcInterface, String lcProperty) {
if (type is! Type) return false;
return this.interfaces(type).contains(lcInterface);
}
List interfaces(type) {
final clazz = reflectType(type);
_assertDeclaresLifecycleHooks(clazz);

View File

@ -197,8 +197,16 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
return {};
}
interfaces(type: Type): any[] {
throw new BaseException("JavaScript does not support interfaces");
// Note: JavaScript does not support to query for interfaces during runtime.
// However, we can't throw here as the reflector will always call this method
// when asked for a lifecycle interface as this is what we check in Dart.
interfaces(type: Type): any[] { return []; }
hasLifecycleHook(type: any, lcInterface: Type, lcProperty: string): boolean {
if (!(type instanceof Type)) return false;
var proto = (<any>type).prototype;
return !!proto[lcProperty];
}
getter(name: string): GetterFn { return <GetterFn>new Function('o', 'return o.' + name + ';'); }

View File

@ -45,9 +45,7 @@ export class Reflector extends ReflectorReader {
this.reflectionCapabilities = reflectionCapabilities;
}
updateCapabilities(caps: PlatformReflectionCapabilities) {
this.reflectionCapabilities = caps;
}
updateCapabilities(caps: PlatformReflectionCapabilities) { this.reflectionCapabilities = caps; }
isReflectionEnabled(): boolean { return this.reflectionCapabilities.isReflectionEnabled(); }
@ -120,7 +118,7 @@ export class Reflector extends ReflectorReader {
}
}
interfaces(type: Type): any[] {
interfaces(type: /*Type*/ any): any[] {
if (this._injectableInfo.has(type)) {
var res = this._getReflectionInfo(type).interfaces;
return isPresent(res) ? res : [];
@ -129,6 +127,15 @@ export class Reflector extends ReflectorReader {
}
}
hasLifecycleHook(type: any, lcInterface: /*Type*/ any, lcProperty: string): boolean {
var interfaces = this.interfaces(type);
if (interfaces.indexOf(lcInterface) !== -1) {
return true;
} else {
return this.reflectionCapabilities.hasLifecycleHook(type, lcInterface, lcProperty);
}
}
getter(name: string): GetterFn {
if (this._getters.has(name)) {
return this._getters.get(name);