fix(ivy): detect frozen flyweight objects in definitions and unfreeze (#25755)
defineComponent() and friends can return a flyweight EMPTY object for specific fields when they contain no data. InheritDefinitionFeature was attempting to write into these flyweight objects, which have been protected with Object.freeze(). This commit adds detection to InheritDefinitionFeature to identify the frozen objects. PR Close #25755
This commit is contained in:

committed by
Misko Hevery

parent
2c66523222
commit
a417b2b419
@ -8,6 +8,7 @@
|
||||
|
||||
import {Type} from '../../type';
|
||||
import {fillProperties} from '../../util/property';
|
||||
import {EMPTY, EMPTY_ARRAY} from '../definition';
|
||||
import {ComponentDefInternal, ComponentTemplate, DirectiveDefFeature, DirectiveDefInternal, RenderFlags} from '../interfaces/definition';
|
||||
|
||||
|
||||
@ -47,6 +48,16 @@ export function InheritDefinitionFeature(
|
||||
}
|
||||
|
||||
const baseDef = (superType as any).ngBaseDef;
|
||||
|
||||
// Some fields in the definition may be empty, if there were no values to put in them that
|
||||
// would've justified object creation. Unwrap them if necessary.
|
||||
if (baseDef || superDef) {
|
||||
const writeableDef = definition as any;
|
||||
writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
|
||||
writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
|
||||
writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
|
||||
}
|
||||
|
||||
if (baseDef) {
|
||||
// Merge inputs and outputs
|
||||
fillProperties(definition.inputs, baseDef.inputs);
|
||||
@ -162,3 +173,15 @@ export function InheritDefinitionFeature(
|
||||
superType = Object.getPrototypeOf(superType);
|
||||
}
|
||||
}
|
||||
|
||||
function maybeUnwrapEmpty<T>(value: T[]): T[];
|
||||
function maybeUnwrapEmpty<T>(value: T): T;
|
||||
function maybeUnwrapEmpty(value: any): any {
|
||||
if (value === EMPTY) {
|
||||
return {};
|
||||
} else if (Array.isArray(value) && value === EMPTY_ARRAY) {
|
||||
return [];
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user