From d9d9e42c23fc8211e3531845106bf986ac2b2b74 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Wed, 14 May 2025 14:54:30 +0200 Subject: [PATCH] fix(core): handle different DI token types in Chrome DevTools integration (#61333) This small refactor makes the DI events reporting code more resiliant with respect to finding names for different token types. PR Close #61333 --- .../debug/chrome_dev_tools_performance.ts | 9 +-- .../chrome_dev_tools_performance_spec.ts | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 packages/core/test/acceptance/chrome_dev_tools_performance_spec.ts diff --git a/packages/core/src/render3/debug/chrome_dev_tools_performance.ts b/packages/core/src/render3/debug/chrome_dev_tools_performance.ts index fdde48e6fa1..96442b690ee 100644 --- a/packages/core/src/render3/debug/chrome_dev_tools_performance.ts +++ b/packages/core/src/render3/debug/chrome_dev_tools_performance.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import {InjectionToken} from '../../di'; import {isTypeProvider} from '../../di/provider_collection'; import {assertDefined, assertEqual} from '../../util/assert'; import {performanceMarkFeature} from '../../util/performance'; @@ -81,7 +80,6 @@ function measureEnd( `Profiling error: expected to see ${startEvent} event but got ${top[0]}`, ); - // Expecting TypeScript error here as overloaded types are not supported yet in TS types console.timeStamp( entryName, 'Event_' + top[0] + '_' + top[1], @@ -216,13 +214,12 @@ function getComponentMeasureName(instance: {}) { } function getProviderTokenMeasureName(token: any) { - if (token instanceof InjectionToken) { - return token.toString(); - } else if (isTypeProvider(token)) { + if (isTypeProvider(token)) { return token.name; - } else { + } else if (token.provide != null) { return getProviderTokenMeasureName(token.provide); } + return token.toString(); } /** diff --git a/packages/core/test/acceptance/chrome_dev_tools_performance_spec.ts b/packages/core/test/acceptance/chrome_dev_tools_performance_spec.ts new file mode 100644 index 00000000000..d6b2c2c102b --- /dev/null +++ b/packages/core/test/acceptance/chrome_dev_tools_performance_spec.ts @@ -0,0 +1,63 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import {enableProfiling} from '../../src/render3/debug/chrome_dev_tools_performance'; +import {Component, HostAttributeToken, inject, Inject} from '../../src/core'; +import {TestBed} from '../../testing'; + +describe('Chrome DevTools Performance integration', () => { + describe('DI perf events', () => { + it('should not crash when a HostAttributeToken is injected', () => { + @Component({ + template: ``, + }) + class MyCmp { + attr = inject(new HostAttributeToken('someAttr'), {optional: true}); + } + + spyOn(console, 'timeStamp'); + const stopProfiling = enableProfiling(); + + try { + const fixture = TestBed.createComponent(MyCmp); + fixture.detectChanges(); + + expect((console.timeStamp as any).calls.all().length).not.toBe(0); + } finally { + stopProfiling(); + } + }); + + it('should not crash when a string provider is injected', () => { + @Component({ + template: ``, + providers: [ + { + provide: 'foo', + useValue: 'bar', + }, + ], + }) + class MyCmp { + constructor(@Inject('foo') foo: string) {} + } + + spyOn(console, 'timeStamp'); + const stopProfiling = enableProfiling(); + + try { + const fixture = TestBed.createComponent(MyCmp); + fixture.detectChanges(); + + expect((console.timeStamp as any).calls.all().length).not.toBe(0); + } finally { + stopProfiling(); + } + }); + }); +});