From 857dfaa1e7b5c502abc095818db934b989783868 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Fri, 19 Mar 2021 07:18:33 +0000 Subject: [PATCH] =?UTF-8?q?refactor(core):=20remove=20the=20need=20for=20`?= =?UTF-8?q?=C9=B5=C9=B5injectPipeChangeDetectorRef()`=20(#41231)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This instruction was created to work around a problem with injecting a `ChangeDetectorRef` into a pipe. See #31438. This fix required special metadata for when the thing being injected was a `ChangeDetectorRef`. Now this is handled by adding a flag `InjectorFlags.ForPipe` to the `ɵɵdirectiveInject()` call, which avoids the need to special test_cases `ChangeDetectorRef` in the generated code. PR Close #41231 --- goldens/public-api/core/core.d.ts | 3 --- goldens/size-tracking/aio-payloads.json | 6 ++--- .../ngcc/test/integration/ngcc_spec.ts | 2 +- .../src/ngtsc/annotations/src/util.ts | 4 --- .../pipes/GOLDEN_PARTIAL.js | 4 +-- ...i_change_detector_ref_my_other_pipe_fac.js | 2 +- ...pipe_di_change_detector_ref_my_pipe_fac.js | 2 +- .../value_composition/GOLDEN_PARTIAL.js | 2 +- .../di/pipe_and_injectable_pipe_first.js | 2 +- .../di/pipe_and_injectable_pipe_last.js | 2 +- .../r3_compiler_compliance_spec.ts | 4 +-- .../r3_view_compiler_di_spec.ts | 4 +-- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 2 +- .../compiler/src/compiler_facade_interface.ts | 3 +-- packages/compiler/src/core.ts | 5 ++++ packages/compiler/src/render3/partial/api.ts | 7 +---- packages/compiler/src/render3/r3_factory.ts | 18 +++---------- .../compiler/src/render3/r3_identifiers.ts | 3 --- packages/compiler/test/core_spec.ts | 3 ++- .../change_detection/change_detector_ref.ts | 26 +++++++------------ .../src/compiler/compiler_facade_interface.ts | 3 +-- .../core/src/core_render3_private_export.ts | 1 - packages/core/src/di/interface/injector.ts | 7 ++++- packages/core/src/di/jit/util.ts | 3 --- packages/core/src/render3/di.ts | 2 +- packages/core/src/render3/index.ts | 2 +- packages/core/src/render3/jit/environment.ts | 1 - .../view_engine_compatibility_prebound.ts | 15 ----------- packages/core/test/render3/render_util.ts | 4 ++- packages/core/test/test_bed_spec.ts | 6 ----- 30 files changed, 50 insertions(+), 98 deletions(-) diff --git a/goldens/public-api/core/core.d.ts b/goldens/public-api/core/core.d.ts index ddbb4e4a90..e5ed21e911 100644 --- a/goldens/public-api/core/core.d.ts +++ b/goldens/public-api/core/core.d.ts @@ -694,9 +694,6 @@ export declare interface ɵɵInjectableDef { /** @codeGenApi */ export declare function ɵɵinjectAttribute(attrNameToInject: string): string | null; -/** @codeGenApi */ -export declare function ɵɵinjectPipeChangeDetectorRef(flags?: InjectFlags): ChangeDetectorRef | null; - export declare const PACKAGE_ROOT_URL: InjectionToken; export declare interface Pipe { diff --git a/goldens/size-tracking/aio-payloads.json b/goldens/size-tracking/aio-payloads.json index 34682b743e..b8d341e40e 100755 --- a/goldens/size-tracking/aio-payloads.json +++ b/goldens/size-tracking/aio-payloads.json @@ -12,8 +12,8 @@ "master": { "uncompressed": { "runtime-es2015": 3033, - "main-es2015": 452165, - "polyfills-es2015": 52493 + "main-es2015": 451600, + "polyfills-es2015": 52215 } } }, @@ -26,4 +26,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts index be13353b9d..3788df438d 100644 --- a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts +++ b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts @@ -823,7 +823,7 @@ runInEachFileSystem(() => { expect(jsContents) .toContain( `TestClass.ɵfac = function TestClass_Factory(t) { ` + - `return new (t || TestClass)(ɵngcc0.ɵɵinjectPipeChangeDetectorRef()); };`); + `return new (t || TestClass)(ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ChangeDetectorRef, 16)); };`); }); it('should use the correct type name in typings files when an export has a different name in source files', diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts index aaa8f2fcfe..2adc004ca6 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts @@ -86,10 +86,6 @@ export function getConstructorDependencies( } }); - if (token instanceof ExternalExpr && token.value.name === 'ChangeDetectorRef' && - token.value.moduleName === '@angular/core') { - resolved = R3ResolvedDependencyType.ChangeDetectorRef; - } if (token === null) { if (param.typeValueReference.kind !== TypeValueReferenceKind.UNAVAILABLE) { throw new Error( diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/GOLDEN_PARTIAL.js index 4b107c3e45..4746dbfb8f 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/GOLDEN_PARTIAL.js @@ -156,7 +156,7 @@ export class MyPipe { return value; } } -MyPipe.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyPipe, deps: [{ token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Pipe }); +MyPipe.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyPipe, deps: [{ token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.Token }], target: i0.ɵɵFactoryTarget.Pipe }); MyPipe.ɵpipe = i0.ɵɵngDeclarePipe({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyPipe, name: "myPipe" }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyPipe, [{ type: Pipe, @@ -168,7 +168,7 @@ export class MyOtherPipe { return value; } } -MyOtherPipe.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyOtherPipe, deps: [{ token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.ChangeDetectorRef, optional: true }], target: i0.ɵɵFactoryTarget.Pipe }); +MyOtherPipe.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyOtherPipe, deps: [{ token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.Token, optional: true }], target: i0.ɵɵFactoryTarget.Pipe }); MyOtherPipe.ɵpipe = i0.ɵɵngDeclarePipe({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyOtherPipe, name: "myOtherPipe" }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyOtherPipe, [{ type: Pipe, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_other_pipe_fac.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_other_pipe_fac.js index e858b8160a..44ed9267f7 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_other_pipe_fac.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_other_pipe_fac.js @@ -1 +1 @@ -MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵinjectPipeChangeDetectorRef(8)); }; +MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($i0$.ɵɵdirectiveInject($i0$.ChangeDetectorRef, 24)); }; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_pipe_fac.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_pipe_fac.js index 9b12d4d695..141e8128d8 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_pipe_fac.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/pipes/pipe_di_change_detector_ref_my_pipe_fac.js @@ -1 +1 @@ -MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)($r3$.ɵɵinjectPipeChangeDetectorRef()); }; +MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)($i0$.ɵɵdirectiveInject($i0$.ChangeDetectorRef, 16)); }; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js index bfaf540821..ee31a55555 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js @@ -206,7 +206,7 @@ export class MyComponent { this.cdr = cdr; } } -MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [{ token: i0.ElementRef, resolved: i0.ɵɵResolvedDependencyType.Token }, { token: i0.ViewContainerRef, resolved: i0.ɵɵResolvedDependencyType.Token }, { token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [{ token: i0.ElementRef, resolved: i0.ɵɵResolvedDependencyType.Token }, { token: i0.ViewContainerRef, resolved: i0.ɵɵResolvedDependencyType.Token }, { token: i0.ChangeDetectorRef, resolved: i0.ɵɵResolvedDependencyType.Token }], target: i0.ɵɵFactoryTarget.Component }); MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: '', isInline: true }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{ type: Component, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_first.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_first.js index 64f769f3df..f9807ae2ab 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_first.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_first.js @@ -1,4 +1,4 @@ // NOTE The prov definition must be last so MyOtherPipe.fac is defined -MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵdirectiveInject(Service)); }; +MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵdirectiveInject(Service, 16)); }; MyOtherPipe.ɵpipe = /*@__PURE__*/ i0.ɵɵdefinePipe({ name: "myOtherPipe", type: MyOtherPipe, pure: true }); MyOtherPipe.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MyOtherPipe, factory: MyOtherPipe.ɵfac }); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_last.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_last.js index 05a6860c53..5a32cb4a0b 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_last.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_di/di/pipe_and_injectable_pipe_last.js @@ -1,4 +1,4 @@ // NOTE The prov definition must be last so MyPipe.fac is defined -MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service)); }; +MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service, 16)); }; MyPipe.ɵpipe = /*@__PURE__*/ i0.ɵɵdefinePipe({ name: "myPipe", type: MyPipe, pure: true }); MyPipe.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MyPipe, factory: MyPipe.ɵfac }); diff --git a/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts index c2d68d83d3..8b99bf37ad 100644 --- a/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts @@ -2294,7 +2294,7 @@ describe('compiler compliance', () => { `; const MyPipeFactory = ` - MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)($r3$.ɵɵinjectPipeChangeDetectorRef()); }; + MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)($i0$.ɵɵdirectiveInject($i0$.ChangeDetectorRef, 16)); }; `; const MyOtherPipeDefinition = ` @@ -2305,7 +2305,7 @@ describe('compiler compliance', () => { });`; const MyOtherPipeFactory = ` - MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵinjectPipeChangeDetectorRef(8)); }; + MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($i0$.ɵɵdirectiveInject($i0$.ChangeDetectorRef, 24)); }; `; const result = compile(files, angularFiles); diff --git a/packages/compiler-cli/test/compliance_old/r3_view_compiler_di_spec.ts b/packages/compiler-cli/test/compliance_old/r3_view_compiler_di_spec.ts index dcd1d1f0d9..94437eca40 100644 --- a/packages/compiler-cli/test/compliance_old/r3_view_compiler_di_spec.ts +++ b/packages/compiler-cli/test/compliance_old/r3_view_compiler_di_spec.ts @@ -372,14 +372,14 @@ describe('compiler compliance: dependency injection', () => { // The prov definition must be last so MyPipe.fac is defined const MyPipeDefs = ` - MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service)); }; + MyPipe.ɵfac = function MyPipe_Factory(t) { return new (t || MyPipe)(i0.ɵɵdirectiveInject(Service, 16)); }; MyPipe.ɵpipe = /*@__PURE__*/ i0.ɵɵdefinePipe({ name: "myPipe", type: MyPipe, pure: true }); MyPipe.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MyPipe, factory: MyPipe.ɵfac }); `; // The prov definition must be last so MyOtherPipe.fac is defined const MyOtherPipeDefs = ` - MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵdirectiveInject(Service)); }; + MyOtherPipe.ɵfac = function MyOtherPipe_Factory(t) { return new (t || MyOtherPipe)($r3$.ɵɵdirectiveInject(Service, 16)); }; MyOtherPipe.ɵpipe = /*@__PURE__*/ i0.ɵɵdefinePipe({ name: "myOtherPipe", type: MyOtherPipe, pure: true }); MyOtherPipe.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MyOtherPipe, factory: MyOtherPipe.ɵfac }); `; diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index f6f221f209..34da420eff 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -1565,7 +1565,7 @@ function allTests(os: string) { env.driveMain(); const jsContents = env.getContents('test.js'); - expect(jsContents).toContain('return new (t || TestPipe)(i0.ɵɵdirectiveInject(Dep));'); + expect(jsContents).toContain('return new (t || TestPipe)(i0.ɵɵdirectiveInject(Dep, 16));'); }); it('should compile Pipes with generic types', () => { diff --git a/packages/compiler/src/compiler_facade_interface.ts b/packages/compiler/src/compiler_facade_interface.ts index c7dc971f6a..6ce8a1d3ce 100644 --- a/packages/compiler/src/compiler_facade_interface.ts +++ b/packages/compiler/src/compiler_facade_interface.ts @@ -86,8 +86,7 @@ export type Provider = any; export enum R3ResolvedDependencyType { Token = 0, Attribute = 1, - ChangeDetectorRef = 2, - Invalid = 3, + Invalid = 2, } export enum R3FactoryTarget { diff --git a/packages/compiler/src/core.ts b/packages/compiler/src/core.ts index a0b07718c3..dc19a925ae 100644 --- a/packages/compiler/src/core.ts +++ b/packages/compiler/src/core.ts @@ -272,6 +272,11 @@ export const enum InjectFlags { SkipSelf = 1 << 2, /** Inject `defaultValue` instead if token not found. */ Optional = 1 << 3, + /** + * This token is being injected into a pipe. + * @internal + */ + ForPipe = 1 << 4, } export const enum ArgumentType { diff --git a/packages/compiler/src/render3/partial/api.ts b/packages/compiler/src/render3/partial/api.ts index 2d9e870e56..283c48d734 100644 --- a/packages/compiler/src/render3/partial/api.ts +++ b/packages/compiler/src/render3/partial/api.ts @@ -432,13 +432,8 @@ export enum R3ResolvedDependencyType { */ Attribute = 1, - /** - * Injecting the `ChangeDetectorRef` token. Needs special handling when injected into a pipe. - */ - ChangeDetectorRef = 2, - /** * An invalid dependency (no token could be determined). An error should be thrown at runtime. */ - Invalid = 3, + Invalid = 2, } diff --git a/packages/compiler/src/render3/r3_factory.ts b/packages/compiler/src/render3/r3_factory.ts index 69bdf819e4..4afb2a94be 100644 --- a/packages/compiler/src/render3/r3_factory.ts +++ b/packages/compiler/src/render3/r3_factory.ts @@ -109,15 +109,10 @@ export enum R3ResolvedDependencyType { */ Attribute = 1, - /** - * Injecting the `ChangeDetectorRef` token. Needs special handling when injected into a pipe. - */ - ChangeDetectorRef = 2, - /** * An invalid dependency (no token could be determined). An error should be thrown at runtime. */ - Invalid = 3, + Invalid = 2, } /** @@ -270,16 +265,14 @@ function injectDependencies(deps: R3DependencyMetadata[], target: R3FactoryTarge function compileInjectDependency( dep: R3DependencyMetadata, target: R3FactoryTarget, index: number): o.Expression { - const isPipe = target === R3FactoryTarget.Pipe; - // Interpret the dependency according to its resolved type. switch (dep.resolved) { case R3ResolvedDependencyType.Token: - case R3ResolvedDependencyType.ChangeDetectorRef: // Build up the injection flags according to the metadata. const flags = InjectFlags.Default | (dep.self ? InjectFlags.Self : 0) | (dep.skipSelf ? InjectFlags.SkipSelf : 0) | (dep.host ? InjectFlags.Host : 0) | - (dep.optional ? InjectFlags.Optional : 0); + (dep.optional ? InjectFlags.Optional : 0) | + (target === R3FactoryTarget.Pipe ? InjectFlags.ForPipe : 0); // If this dependency is optional or otherwise has non-default flags, then additional // parameters describing how to inject the dependency must be passed to the inject function @@ -287,11 +280,6 @@ function compileInjectDependency( let flagsParam: o.LiteralExpr|null = (flags !== InjectFlags.Default || dep.optional) ? o.literal(flags) : null; - // We have a separate instruction for injecting ChangeDetectorRef into a pipe. - if (isPipe && dep.resolved === R3ResolvedDependencyType.ChangeDetectorRef) { - return o.importExpr(R3.injectPipeChangeDetectorRef).callFn(flagsParam ? [flagsParam] : []); - } - // Build up the arguments to the injectFn call. const injectArgs = [dep.token]; if (flagsParam) { diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index e785096f18..4c10ec3e58 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -219,9 +219,6 @@ export class Identifiers { static injectAttribute: o.ExternalReference = {name: 'ɵɵinjectAttribute', moduleName: CORE}; - static injectPipeChangeDetectorRef: - o.ExternalReference = {name: 'ɵɵinjectPipeChangeDetectorRef', moduleName: CORE}; - static directiveInject: o.ExternalReference = {name: 'ɵɵdirectiveInject', moduleName: CORE}; static invalidFactory: o.ExternalReference = {name: 'ɵɵinvalidFactory', moduleName: CORE}; static invalidFactoryDep: o.ExternalReference = {name: 'ɵɵinvalidFactoryDep', moduleName: CORE}; diff --git a/packages/compiler/test/core_spec.ts b/packages/compiler/test/core_spec.ts index cf045725a0..6e98b952c4 100644 --- a/packages/compiler/test/core_spec.ts +++ b/packages/compiler/test/core_spec.ts @@ -153,7 +153,8 @@ import * as core from '@angular/core'; expectToBe(compilerCore.InjectFlags.Default, core.InjectFlags.Default); expectToBe(compilerCore.InjectFlags.SkipSelf, core.InjectFlags.SkipSelf); expectToBe(compilerCore.InjectFlags.Self, core.InjectFlags.Self); - + expectToBe(compilerCore.InjectFlags.Host, core.InjectFlags.Host); + expectToBe(compilerCore.InjectFlags.Optional, core.InjectFlags.Optional); expectToBe(compilerCore.ArgumentType.Inline, core.ɵArgumentType.Inline); expectToBe(compilerCore.ArgumentType.Dynamic, core.ɵArgumentType.Dynamic); diff --git a/packages/core/src/change_detection/change_detector_ref.ts b/packages/core/src/change_detection/change_detector_ref.ts index 898fb38866..ad805d2484 100644 --- a/packages/core/src/change_detection/change_detector_ref.ts +++ b/packages/core/src/change_detection/change_detector_ref.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +import {InjectFlags} from '../di'; +import {InternalInjectFlags} from '../di/interface/injector'; import {TNode, TNodeType} from '../render3/interfaces/node'; import {isComponentHost} from '../render3/interfaces/type_checks'; import {DECLARATION_COMPONENT_VIEW, LView} from '../render3/interfaces/view'; @@ -125,22 +127,17 @@ export abstract class ChangeDetectorRef { * @internal * @nocollapse */ - static __NG_ELEMENT_ID__: () => ChangeDetectorRef = SWITCH_CHANGE_DETECTOR_REF_FACTORY; - - /** - * This marker is need so that the JIT compiler can correctly identify this class as special. - * - * @internal - * @nocollapse - */ - static __ChangeDetectorRef__ = true; + static __NG_ELEMENT_ID__: + (flags: InjectFlags) => ChangeDetectorRef = SWITCH_CHANGE_DETECTOR_REF_FACTORY; } /** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */ -export function injectChangeDetectorRef(isPipe = false): ChangeDetectorRef { - return createViewRef(getCurrentTNode()!, getLView(), isPipe); +export function injectChangeDetectorRef(flags: InjectFlags): ChangeDetectorRef { + return createViewRef( + getCurrentTNode()!, getLView(), + (flags & InternalInjectFlags.ForPipe) === InternalInjectFlags.ForPipe); } /** @@ -152,10 +149,7 @@ export function injectChangeDetectorRef(isPipe = false): ChangeDetectorRef { * @returns The ChangeDetectorRef to use */ function createViewRef(tNode: TNode, lView: LView, isPipe: boolean): ChangeDetectorRef { - // `isComponentView` will be true for Component and Directives (but not for Pipes). - // See https://github.com/angular/angular/pull/33072 for proper fix - const isComponentView = !isPipe && isComponentHost(tNode); - if (isComponentView) { + if (isComponentHost(tNode) && !isPipe) { // The LView represents the location where the component is declared. // Instead we want the LView for the component View and so we need to look it up. const componentView = getComponentLViewByIndex(tNode.index, lView); // look down @@ -167,4 +161,4 @@ function createViewRef(tNode: TNode, lView: LView, isPipe: boolean): ChangeDetec return new R3_ViewRef(hostComponentView, lView); } return null!; -} \ No newline at end of file +} diff --git a/packages/core/src/compiler/compiler_facade_interface.ts b/packages/core/src/compiler/compiler_facade_interface.ts index c7dc971f6a..6ce8a1d3ce 100644 --- a/packages/core/src/compiler/compiler_facade_interface.ts +++ b/packages/core/src/compiler/compiler_facade_interface.ts @@ -86,8 +86,7 @@ export type Provider = any; export enum R3ResolvedDependencyType { Token = 0, Attribute = 1, - ChangeDetectorRef = 2, - Invalid = 3, + Invalid = 2, } export enum R3FactoryTarget { diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 8b830bfdb2..393f16c16d 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -154,7 +154,6 @@ export { ɵɵInheritDefinitionFeature, ɵɵinjectAttribute, ɵɵInjectorDeclaration, - ɵɵinjectPipeChangeDetectorRef, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, diff --git a/packages/core/src/di/interface/injector.ts b/packages/core/src/di/interface/injector.ts index 7d11dd5980..276e116c2d 100644 --- a/packages/core/src/di/interface/injector.ts +++ b/packages/core/src/di/interface/injector.ts @@ -70,4 +70,9 @@ export const enum InternalInjectFlags { /** Inject `defaultValue` instead if token not found. */ Optional = 0b1000, -} \ No newline at end of file + + /** + * This token is being injected into a pipe. + */ + ForPipe = 0b10000, +} diff --git a/packages/core/src/di/jit/util.ts b/packages/core/src/di/jit/util.ts index 7fa1880016..06f44565de 100644 --- a/packages/core/src/di/jit/util.ts +++ b/packages/core/src/di/jit/util.ts @@ -68,9 +68,6 @@ function reflectDependency(compiler: CompilerFacade, dep: any|any[]): R3Dependen } meta.token = param.attributeName; meta.resolved = compiler.R3ResolvedDependencyType.Attribute; - } else if (param.__ChangeDetectorRef__ === true) { - meta.token = param; - meta.resolved = compiler.R3ResolvedDependencyType.ChangeDetectorRef; } else { setTokenAndResolvedType(param); } diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index 42027cd56b..0a634787bd 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -421,7 +421,7 @@ export function getOrCreateInjectable( lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue); } try { - const value = bloomHash(); + const value = bloomHash(flags); if (value == null && !(flags & InjectFlags.Optional)) { throwProviderNotFoundError(token); } else { diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 417f266912..aa8b010bce 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -172,7 +172,7 @@ export { } from './state'; export {NO_CHANGE} from './tokens'; export { ɵɵresolveBody, ɵɵresolveDocument,ɵɵresolveWindow} from './util/misc_utils'; -export { ɵɵinjectPipeChangeDetectorRef,ɵɵtemplateRefExtractor} from './view_engine_compatibility_prebound'; +export { ɵɵtemplateRefExtractor} from './view_engine_compatibility_prebound'; // clang-format on export { diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index 8486e40655..697c090c15 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -42,7 +42,6 @@ export const angularCoreEnv: {[name: string]: Function} = 'ɵɵinjectAttribute': r3.ɵɵinjectAttribute, 'ɵɵinvalidFactory': r3.ɵɵinvalidFactory, 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep, - 'ɵɵinjectPipeChangeDetectorRef': r3.ɵɵinjectPipeChangeDetectorRef, 'ɵɵtemplateRefExtractor': r3.ɵɵtemplateRefExtractor, 'ɵɵNgOnChangesFeature': r3.ɵɵNgOnChangesFeature, 'ɵɵProvidersFeature': r3.ɵɵProvidersFeature, diff --git a/packages/core/src/render3/view_engine_compatibility_prebound.ts b/packages/core/src/render3/view_engine_compatibility_prebound.ts index 0298259f0c..9e9f5bf657 100644 --- a/packages/core/src/render3/view_engine_compatibility_prebound.ts +++ b/packages/core/src/render3/view_engine_compatibility_prebound.ts @@ -24,18 +24,3 @@ import {LView} from './interfaces/view'; export function ɵɵtemplateRefExtractor(tNode: TNode, lView: LView): TemplateRef|null { return createTemplateRef(tNode, lView); } - - -/** - * Returns the appropriate `ChangeDetectorRef` for a pipe. - * - * @codeGenApi - */ -export function ɵɵinjectPipeChangeDetectorRef(flags = InjectFlags.Default): ChangeDetectorRef|null { - const value = injectChangeDetectorRef(true); - if (value == null && !(flags & InjectFlags.Optional)) { - throwProviderNotFoundError('ChangeDetectorRef'); - } else { - return value; - } -} diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 8537c7d574..3c9d467393 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -8,6 +8,7 @@ import {RendererStyleFlags2, RendererType2} from '@angular/core'; import {ChangeDetectorRef} from '@angular/core/src/change_detection/change_detector_ref'; +import {InjectFlags} from '@angular/core/src/di'; import {Provider} from '@angular/core/src/di/interface/provider'; import {ElementRef} from '@angular/core/src/linker/element_ref'; import {TemplateRef} from '@angular/core/src/linker/template_ref'; @@ -459,7 +460,8 @@ export function enableIvyInjectableFactories() { (ElementRef as any)[NG_ELEMENT_ID] = () => R3_ELEMENT_REF_FACTORY(); (TemplateRef as any)[NG_ELEMENT_ID] = () => R3_TEMPLATE_REF_FACTORY(); (ViewContainerRef as any)[NG_ELEMENT_ID] = () => R3_VIEW_CONTAINER_REF_FACTORY(); - (ChangeDetectorRef as any)[NG_ELEMENT_ID] = () => R3_CHANGE_DETECTOR_REF_FACTORY(); + (ChangeDetectorRef as any)[NG_ELEMENT_ID] = (flags: InjectFlags) => + R3_CHANGE_DETECTOR_REF_FACTORY(flags); (Renderer2 as any)[NG_ELEMENT_ID] = () => R3_RENDERER2_FACTORY(); } diff --git a/packages/core/test/test_bed_spec.ts b/packages/core/test/test_bed_spec.ts index 7598cd1246..3031801161 100644 --- a/packages/core/test/test_bed_spec.ts +++ b/packages/core/test/test_bed_spec.ts @@ -627,12 +627,6 @@ describe('TestBed', () => { }); it('should handle overrides for a provider that has `ChangeDetectorRef` as a dependency', () => { - // Note: we specifically check an @Injectable with `ChangeDetectorRef` here due to the fact that - // in Ivy there is a special instruction that injects `ChangeDetectorRef` token for Pipes - // (ɵɵinjectPipeChangeDetectorRef) and using that function for other types causes problems, - // for example when we try to override an @Injectable. The test below captures a use-case that - // triggers a problem in case incompatible function is used to inject `ChangeDetectorRef` as a - // dependency. @Injectable({providedIn: 'root'}) class MyService { token = 'original';