feat(ivy): support inheriting input/output from bare base class (#25094)

PR Close #25094
This commit is contained in:
Ben Lesh
2018-07-23 17:01:22 -07:00
committed by Igor Minar
parent 6e2a1877ab
commit 64516da6b0
9 changed files with 378 additions and 62 deletions

View File

@ -7,22 +7,10 @@
*/
import {Type} from '../../type';
import {ComponentDefInternal, ComponentType, DirectiveDefFeature, DirectiveDefInternal} from '../interfaces/definition';
import {fillProperties} from '../../util/property';
import {ComponentDefInternal, DirectiveDefFeature, DirectiveDefInternal} from '../interfaces/definition';
/**
* Sets properties on a target object from a source object, but only if
* the property doesn't already exist on the target object.
* @param target The target to set properties on
* @param source The source of the property keys and values to set
*/
function fillProperties(target: {[key: string]: string}, source: {[key: string]: string}) {
for (const key in source) {
if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}
/**
* Determines if a definition is a {@link ComponentDefInternal} or a {@link DirectiveDefInternal}
* @param definition The definition to examine
@ -45,9 +33,9 @@ function getSuperType(type: Type<any>): Type<any>&
export function InheritDefinitionFeature(
definition: DirectiveDefInternal<any>| ComponentDefInternal<any>): void {
let superType = getSuperType(definition.type);
let superDef: DirectiveDefInternal<any>|ComponentDefInternal<any>|undefined = undefined;
while (superType && !superDef) {
while (superType) {
let superDef: DirectiveDefInternal<any>|ComponentDefInternal<any>|undefined = undefined;
if (isComponentDef(definition)) {
superDef = superType.ngComponentDef || superType.ngDirectiveDef;
} else {
@ -57,12 +45,15 @@ export function InheritDefinitionFeature(
superDef = superType.ngDirectiveDef;
}
if (superDef) {
const baseDef = (superType as any).ngBaseDef;
if (baseDef) {
// Merge inputs and outputs
fillProperties(definition.inputs, superDef.inputs);
fillProperties(definition.declaredInputs, superDef.declaredInputs);
fillProperties(definition.outputs, superDef.outputs);
fillProperties(definition.inputs, baseDef.inputs);
fillProperties(definition.declaredInputs, baseDef.declaredInputs);
fillProperties(definition.outputs, baseDef.outputs);
}
if (superDef) {
// Merge hostBindings
const prevHostBindings = definition.hostBindings;
const superHostBindings = superDef.hostBindings;
@ -77,6 +68,11 @@ export function InheritDefinitionFeature(
}
}
// Merge inputs and outputs
fillProperties(definition.inputs, superDef.inputs);
fillProperties(definition.declaredInputs, superDef.declaredInputs);
fillProperties(definition.outputs, superDef.outputs);
// Inherit hooks
// Assume super class inheritance feature has already run.
definition.afterContentChecked =
@ -97,6 +93,8 @@ export function InheritDefinitionFeature(
}
}
}
break;
} else {
// Even if we don't have a definition, check the type for the hooks and use those if need be
const superPrototype = superType.prototype;