Skip to content

Commit 0c0698a

Browse files
refactor(compiler): rename R3ProviderExpression and associated helpers
This interface will be used in other situations so this change renames it to be more general as `MaybeForwardRefExpression`.
1 parent 8a99ef1 commit 0c0698a

File tree

10 files changed

+103
-102
lines changed

10 files changed

+103
-102
lines changed

packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_injectable_linker_1.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {compileInjectable, ConstantPool, createR3ProviderExpression, R3DeclareInjectableMetadata, R3InjectableMetadata, R3PartialDeclaration} from '@angular/compiler';
8+
import {compileInjectable, ConstantPool, createMayBeForwardRefExpression, R3DeclareInjectableMetadata, R3InjectableMetadata, R3PartialDeclaration} from '@angular/compiler';
99
import * as o from '@angular/compiler/src/output/output_ast';
1010

1111
import {AstObject} from '../../ast/ast_value';
@@ -45,7 +45,7 @@ export function toR3InjectableMeta<TExpression>(
4545
internalType: typeExpr.getOpaque(),
4646
typeArgumentCount: 0,
4747
providedIn: metaObj.has('providedIn') ? extractForwardRef(metaObj.getValue('providedIn')) :
48-
createR3ProviderExpression(o.literal(null), false),
48+
createMayBeForwardRefExpression(o.literal(null), false),
4949
};
5050

5151
if (metaObj.has('useClass')) {

packages/compiler-cli/linker/src/file_linker/partial_linkers/util.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {createR3ProviderExpression, R3DeclareDependencyMetadata, R3DependencyMetadata, R3ProviderExpression, R3Reference} from '@angular/compiler';
8+
import {createMayBeForwardRefExpression, MaybeForwardRefExpression, R3DeclareDependencyMetadata, R3DependencyMetadata, R3Reference} from '@angular/compiler';
99
import * as o from '@angular/compiler/src/output/output_ast';
1010

1111
import {AstObject, AstValue} from '../../ast/ast_value';
@@ -67,9 +67,9 @@ export function getDependency<TExpression>(
6767
* If there is no forwardRef call expression then we just return the opaque type.
6868
*/
6969
export function extractForwardRef<TExpression>(expr: AstValue<unknown, TExpression>):
70-
R3ProviderExpression<o.WrappedNodeExpr<TExpression>> {
70+
MaybeForwardRefExpression<o.WrappedNodeExpr<TExpression>> {
7171
if (!expr.isCallExpression()) {
72-
return createR3ProviderExpression(expr.getOpaque(), /* isForwardRef */ false);
72+
return createMayBeForwardRefExpression(expr.getOpaque(), /* isForwardRef */ false);
7373
}
7474

7575
const callee = expr.getCallee();
@@ -91,5 +91,5 @@ export function extractForwardRef<TExpression>(expr: AstValue<unknown, TExpressi
9191
wrapperFn, 'Unsupported `forwardRef(fn)` call, expected its argument to be a function');
9292
}
9393

94-
return createR3ProviderExpression(wrapperFn.getFunctionReturnValue().getOpaque(), true);
94+
return createMayBeForwardRefExpression(wrapperFn.getFunctionReturnValue().getOpaque(), true);
9595
}

packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {compileClassMetadata, CompileClassMetadataFn, compileDeclareClassMetadata, compileDeclareInjectableFromMetadata, compileInjectable, createR3ProviderExpression, Expression, FactoryTarget, LiteralExpr, R3ClassMetadata, R3CompiledExpression, R3DependencyMetadata, R3InjectableMetadata, R3ProviderExpression, Statement, WrappedNodeExpr} from '@angular/compiler';
9+
import {compileClassMetadata, CompileClassMetadataFn, compileDeclareClassMetadata, compileDeclareInjectableFromMetadata, compileInjectable, createMayBeForwardRefExpression, FactoryTarget, LiteralExpr, MaybeForwardRefExpression, R3ClassMetadata, R3CompiledExpression, R3DependencyMetadata, R3InjectableMetadata, WrappedNodeExpr} from '@angular/compiler';
1010
import * as ts from 'typescript';
1111

1212
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
@@ -162,7 +162,7 @@ function extractInjectableMetadata(
162162
type,
163163
typeArgumentCount,
164164
internalType,
165-
providedIn: createR3ProviderExpression(new LiteralExpr(null), false),
165+
providedIn: createMayBeForwardRefExpression(new LiteralExpr(null), false),
166166
};
167167
} else if (decorator.args.length === 1) {
168168
const metaNode = decorator.args[0];
@@ -180,7 +180,7 @@ function extractInjectableMetadata(
180180

181181
const providedIn = meta.has('providedIn') ?
182182
getProviderExpression(meta.get('providedIn')!, reflector) :
183-
createR3ProviderExpression(new LiteralExpr(null), false);
183+
createMayBeForwardRefExpression(new LiteralExpr(null), false);
184184

185185
let deps: R3DependencyMetadata[]|undefined = undefined;
186186
if ((meta.has('useClass') || meta.has('useFactory')) && meta.has('deps')) {
@@ -220,9 +220,9 @@ function extractInjectableMetadata(
220220
* object to indicate whether the value needed unwrapping.
221221
*/
222222
function getProviderExpression(
223-
expression: ts.Expression, reflector: ReflectionHost): R3ProviderExpression {
223+
expression: ts.Expression, reflector: ReflectionHost): MaybeForwardRefExpression {
224224
const forwardRefValue = tryUnwrapForwardRef(expression, reflector);
225-
return createR3ProviderExpression(
225+
return createMayBeForwardRefExpression(
226226
new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null);
227227
}
228228

packages/compiler/src/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export {compileNgModule, R3NgModuleMetadata} from './render3/r3_module_compiler'
103103
export {compileInjector, R3InjectorMetadata} from './render3/r3_injector_compiler';
104104
export {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compiler';
105105
export {makeBindingParser, ParsedTemplate, parseTemplate, ParseTemplateOptions} from './render3/view/template';
106-
export {R3CompiledExpression, R3Reference, devOnlyGuardedExpression, getSafePropertyAccessString} from './render3/util';
106+
export {MaybeForwardRefExpression, R3CompiledExpression, R3Reference, createMayBeForwardRefExpression, devOnlyGuardedExpression, getSafePropertyAccessString} from './render3/util';
107107
export {compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings, ParsedHostBindings, verifyHostBindings} from './render3/view/compiler';
108108
export {compileDeclareClassMetadata} from './render3/partial/class_metadata';
109109
export {compileDeclareComponentFromMetadata, DeclareComponentTemplateInfo} from './render3/partial/component';

packages/compiler/src/injectable_compiler_2.ts

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,24 @@
77
*/
88

99
import * as o from './output/output_ast';
10-
import {generateForwardRef} from './render3/partial/util';
1110
import {compileFactoryFunction, FactoryTarget, R3DependencyMetadata, R3FactoryDelegateType, R3FactoryMetadata} from './render3/r3_factory';
1211
import {Identifiers} from './render3/r3_identifiers';
13-
import {R3CompiledExpression, R3Reference, typeWithParameters} from './render3/util';
12+
import {generateForwardRef, MaybeForwardRefExpression, R3CompiledExpression, R3Reference, typeWithParameters} from './render3/util';
1413
import {DefinitionMap} from './render3/view/util';
1514

1615
export interface R3InjectableMetadata {
1716
name: string;
1817
type: R3Reference;
1918
internalType: o.Expression;
2019
typeArgumentCount: number;
21-
providedIn: R3ProviderExpression;
22-
useClass?: R3ProviderExpression;
20+
providedIn: MaybeForwardRefExpression;
21+
useClass?: MaybeForwardRefExpression;
2322
useFactory?: o.Expression;
24-
useExisting?: R3ProviderExpression;
25-
useValue?: R3ProviderExpression;
23+
useExisting?: MaybeForwardRefExpression;
24+
useValue?: MaybeForwardRefExpression;
2625
deps?: R3DependencyMetadata[];
2726
}
2827

29-
/**
30-
* An expression used when instantiating an injectable.
31-
*
32-
* This is the type of the `useClass`, `useExisting` and `useValue` properties of
33-
* `R3InjectableMetadata` since those can refer to types that may eagerly reference types that have
34-
* not yet been defined.
35-
*/
36-
export interface R3ProviderExpression<T extends o.Expression = o.Expression> {
37-
/**
38-
* The expression that is used to instantiate the Injectable.
39-
*/
40-
expression: T;
41-
/**
42-
* If true, then the `expression` contains a reference to something that has not yet been
43-
* defined.
44-
*
45-
* This means that the expression must not be eagerly evaluated. Instead it must be wrapped in a
46-
* function closure that will be evaluated lazily to allow the definition of the expression to be
47-
* evaluated first.
48-
*
49-
* In some cases the expression will naturally be placed inside such a function closure, such as
50-
* in a fully compiled factory function. In those case nothing more needs to be done.
51-
*
52-
* But in other cases, such as partial-compilation the expression will be located in top level
53-
* code so will need to be wrapped in a function that is passed to a `forwardRef()` call.
54-
*/
55-
isForwardRef: boolean;
56-
}
57-
58-
export function createR3ProviderExpression<T extends o.Expression>(
59-
expression: T, isForwardRef: boolean): R3ProviderExpression<T> {
60-
return {expression, isForwardRef};
61-
}
62-
6328
export function compileInjectable(
6429
meta: R3InjectableMetadata, resolveForwardRefs: boolean): R3CompiledExpression {
6530
let result: {expression: o.Expression, statements: o.Statement[]}|null = null;

packages/compiler/src/jit_compiler_facade.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, OpaqueValue, R3ComponentMetadataFacade, R3DeclareComponentFacade, R3DeclareDependencyMetadataFacade, R3DeclareDirectiveFacade, R3DeclareFactoryFacade, R3DeclareInjectableFacade, R3DeclareInjectorFacade, R3DeclareNgModuleFacade, R3DeclarePipeFacade, R3DeclareQueryMetadataFacade, R3DeclareUsedDirectiveFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3FactoryDefMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
1111
import {ConstantPool} from './constant_pool';
1212
import {ChangeDetectionStrategy, HostBinding, HostListener, Input, Output, ViewEncapsulation} from './core';
13-
import {compileInjectable, createR3ProviderExpression, R3ProviderExpression} from './injectable_compiler_2';
13+
import {compileInjectable} from './injectable_compiler_2';
1414
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './ml_parser/interpolation_config';
1515
import {DeclareVarStmt, Expression, literal, LiteralExpr, Statement, StmtModifier, WrappedNodeExpr} from './output/output_ast';
1616
import {JitEvaluator} from './output/output_jit';
@@ -20,7 +20,7 @@ import {compileInjector, R3InjectorMetadata} from './render3/r3_injector_compile
2020
import {R3JitReflector} from './render3/r3_jit';
2121
import {compileNgModule, compileNgModuleDeclarationExpression, R3NgModuleMetadata} from './render3/r3_module_compiler';
2222
import {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compiler';
23-
import {getSafePropertyAccessString, wrapReference} from './render3/util';
23+
import {createMayBeForwardRefExpression, getSafePropertyAccessString, MaybeForwardRefExpression, wrapReference} from './render3/util';
2424
import {DeclarationListEmitMode, R3ComponentMetadata, R3DirectiveMetadata, R3HostMetadata, R3QueryMetadata, R3UsedDirectiveMetadata} from './render3/view/api';
2525
import {compileComponentFromMetadata, compileDirectiveFromMetadata, ParsedHostBindings, parseHostBindings, verifyHostBindings} from './render3/view/compiler';
2626
import {makeBindingParser, parseTemplate} from './render3/view/template';
@@ -478,9 +478,11 @@ type R3DirectiveMetadataFacadeNoPropAndWhitespace =
478478
* a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
479479
* set `isForwardRef` to `false`.
480480
*/
481-
function convertToProviderExpression(obj: any, property: string): R3ProviderExpression|undefined {
481+
function convertToProviderExpression(obj: any, property: string): MaybeForwardRefExpression|
482+
undefined {
482483
if (obj.hasOwnProperty(property)) {
483-
return createR3ProviderExpression(new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
484+
return createMayBeForwardRefExpression(
485+
new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
484486
} else {
485487
return undefined;
486488
}
@@ -494,12 +496,12 @@ function wrapExpression(obj: any, property: string): WrappedNodeExpr<any>|undefi
494496
}
495497
}
496498

497-
function computeProvidedIn(providedIn: Function|string|null|undefined): R3ProviderExpression {
499+
function computeProvidedIn(providedIn: Function|string|null|undefined): MaybeForwardRefExpression {
498500
const expression = (providedIn == null || typeof providedIn === 'string') ?
499501
new LiteralExpr(providedIn ?? null) :
500502
new WrappedNodeExpr(providedIn);
501503
// See `convertToProviderExpression()` for why `isForwardRef` is false.
502-
return createR3ProviderExpression(expression, /* isForwardRef */ false);
504+
return createMayBeForwardRefExpression(expression, /* isForwardRef */ false);
503505
}
504506

505507
function convertR3DependencyMetadataArray(facades: R3DependencyMetadataFacade[]|null|

packages/compiler/src/render3/partial/component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import {DEFAULT_INTERPOLATION_CONFIG} from '../../ml_parser/interpolation_config
1010
import * as o from '../../output/output_ast';
1111
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../parse_util';
1212
import {Identifiers as R3} from '../r3_identifiers';
13-
import {R3CompiledExpression} from '../util';
13+
import {generateForwardRef, R3CompiledExpression} from '../util';
1414
import {DeclarationListEmitMode, R3ComponentMetadata, R3UsedDirectiveMetadata} from '../view/api';
1515
import {createComponentType} from '../view/compiler';
1616
import {ParsedTemplate} from '../view/template';
1717
import {DefinitionMap} from '../view/util';
1818

1919
import {R3DeclareComponentMetadata, R3DeclareUsedDirectiveMetadata} from './api';
2020
import {createDirectiveDefinitionMap} from './directive';
21-
import {generateForwardRef, toOptionalLiteralArray} from './util';
21+
import {toOptionalLiteralArray} from './util';
2222

2323
export interface DeclareComponentTemplateInfo {
2424
/**

packages/compiler/src/render3/partial/injectable.ts

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {createInjectableType, R3InjectableMetadata, R3ProviderExpression} from '../../injectable_compiler_2';
8+
import {createInjectableType, R3InjectableMetadata} from '../../injectable_compiler_2';
99
import * as o from '../../output/output_ast';
1010
import {Identifiers as R3} from '../r3_identifiers';
11-
import {R3CompiledExpression} from '../util';
11+
import {convertFromMaybeForwardRefExpression, R3CompiledExpression} from '../util';
1212
import {DefinitionMap} from '../view/util';
1313

1414
import {R3DeclareInjectableMetadata} from './api';
15-
import {compileDependency, generateForwardRef} from './util';
15+
import {compileDependency} from './util';
1616

1717
/**
1818
* Every time we make a breaking change to the declaration interface or partial-linker behavior, we
@@ -50,20 +50,20 @@ export function createInjectableDefinitionMap(meta: R3InjectableMetadata):
5050

5151
// Only generate providedIn property if it has a non-null value
5252
if (meta.providedIn !== undefined) {
53-
const providedIn = convertFromProviderExpression(meta.providedIn);
53+
const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
5454
if ((providedIn as o.LiteralExpr).value !== null) {
5555
definitionMap.set('providedIn', providedIn);
5656
}
5757
}
5858

5959
if (meta.useClass !== undefined) {
60-
definitionMap.set('useClass', convertFromProviderExpression(meta.useClass));
60+
definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
6161
}
6262
if (meta.useExisting !== undefined) {
63-
definitionMap.set('useExisting', convertFromProviderExpression(meta.useExisting));
63+
definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
6464
}
6565
if (meta.useValue !== undefined) {
66-
definitionMap.set('useValue', convertFromProviderExpression(meta.useValue));
66+
definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
6767
}
6868
// Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
6969
// so the types will not be eagerly evaluated. Therefore we do not need to process this expression
@@ -78,26 +78,3 @@ export function createInjectableDefinitionMap(meta: R3InjectableMetadata):
7878

7979
return definitionMap;
8080
}
81-
82-
/**
83-
* Convert an `R3ProviderExpression` to an `Expression`, possibly wrapping its expression in a
84-
* `forwardRef()` call.
85-
*
86-
* If `R3ProviderExpression.isForwardRef` is true then the expression was originally wrapped in a
87-
* `forwardRef()` call to prevent the value from being eagerly evaluated in the code.
88-
*
89-
* Normally, the linker will statically process the code, putting the `expression` inside a factory
90-
* function so the `forwardRef()` wrapper is not evaluated before it has been defined. But if the
91-
* partial declaration is evaluated by the JIT compiler the `forwardRef()` call is still needed to
92-
* prevent eager evaluation of the `expression`.
93-
*
94-
* So in partial declarations, expressions that could be forward-refs are wrapped in `forwardRef()`
95-
* calls, and this is then unwrapped in the linker as necessary.
96-
*
97-
* See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
98-
* `packages/compiler/src/jit_compiler_facade.ts` for more information.
99-
*/
100-
function convertFromProviderExpression({expression, isForwardRef}: R3ProviderExpression):
101-
o.Expression {
102-
return isForwardRef ? generateForwardRef(expression) : expression;
103-
}

packages/compiler/src/render3/partial/util.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88
import * as o from '../../output/output_ast';
99
import {R3DependencyMetadata} from '../r3_factory';
10-
import {Identifiers} from '../r3_identifiers';
1110
import {DefinitionMap} from '../view/util';
1211
import {R3DeclareDependencyMetadata} from './api';
1312

@@ -84,14 +83,3 @@ export function compileDependency(dep: R3DependencyMetadata): o.LiteralMapExpr {
8483
}
8584
return depMeta.toLiteralMap();
8685
}
87-
88-
/**
89-
* Generate an expression that has the given `expr` wrapped in the following form:
90-
*
91-
* ```
92-
* forwardRef(() => expr)
93-
* ```
94-
*/
95-
export function generateForwardRef(expr: o.Expression): o.Expression {
96-
return o.importExpr(Identifiers.forwardRef).callFn([o.fn([], [new o.ReturnStatement(expr)])]);
97-
}

0 commit comments

Comments
 (0)