fix(ivy): support string tokens in dependency injection (#27383)
In Angular, it used to be an accepted practice to use strings as dependency injection tokens. E.g. {provide: 'test', useValue: 'provided'}. However, the Ivy node injection system did not support this. The Ivy DI system attempts to patch a Bloom bit index onto each type registered with it, and this patch operation does not work for a string token. This commit adds string token support to the bloom filter system by reserving bit 0 for string tokens. This eliminates the need for each string token to store its own Bloom bit, at the expense of slightly more expensive lookups of string tokens. PR Close #27383
This commit is contained in:

committed by
Igor Minar

parent
c96dea27ce
commit
64a34616d8
@ -87,9 +87,10 @@ let nextNgElementId = 0;
|
||||
* @param type The directive token to register
|
||||
*/
|
||||
export function bloomAdd(
|
||||
injectorIndex: number, tView: TView, type: Type<any>| InjectionToken<any>): void {
|
||||
injectorIndex: number, tView: TView, type: Type<any>| InjectionToken<any>| string): void {
|
||||
ngDevMode && assertEqual(tView.firstTemplatePass, true, 'expected firstTemplatePass to be true');
|
||||
let id: number|undefined = (type as any)[NG_ELEMENT_ID];
|
||||
let id: number|undefined =
|
||||
typeof type !== 'string' ? (type as any)[NG_ELEMENT_ID] : type.charCodeAt(0) || 0;
|
||||
|
||||
// Set a unique ID on the directive type, so if something tries to inject the directive,
|
||||
// we can easily retrieve the ID and hash it into the bloom bit that should be checked.
|
||||
@ -502,9 +503,12 @@ export function getNodeInjectable(
|
||||
* @param token the injection token
|
||||
* @returns the matching bit to check in the bloom filter or `null` if the token is not known.
|
||||
*/
|
||||
export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): number|Function|
|
||||
undefined {
|
||||
export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>| string): number|
|
||||
Function|undefined {
|
||||
ngDevMode && assertDefined(token, 'token must be defined');
|
||||
if (typeof token === 'string') {
|
||||
return token.charCodeAt(0) || 0;
|
||||
}
|
||||
const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID];
|
||||
return typeof tokenId === 'number' ? tokenId & BLOOM_MASK : tokenId;
|
||||
}
|
||||
|
Reference in New Issue
Block a user