feat(compiler-cli): lower metadata useValue
and data
literal fields (#18905)
With this commit the compiler will "lower" expressions into exported variables for values the compiler does not need to know statically in order to be able to generate a factory. For example: ``` providers: [{provider: 'token', useValue: calculated()}] ``` produced an error as the expression `calculated()` is not supported by the compiler because `calculated` is not a [known function](https://angular.io/guide/metadata#annotationsdecorators) With this commit this is rewritten, during emit of the .js file, into something like: ``` export var ɵ0 = calculated(); ... provdiers: [{provider: 'token', useValue: ɵ0}] ``` The compiler then will now generate a reference to the exported `ɵ0` instead of failing to evaluate `calculated()`. PR Close #18905
This commit is contained in:

committed by
Jason Aden

parent
2f2d5f35bd
commit
c685cc2f0a
@ -35,12 +35,14 @@ export function debugOutputAstAsTypeScript(ast: o.Statement | o.Expression | o.T
|
||||
return ctx.toSource();
|
||||
}
|
||||
|
||||
export type ReferenceFilter = (reference: o.ExternalReference) => boolean;
|
||||
|
||||
export class TypeScriptEmitter implements OutputEmitter {
|
||||
emitStatementsAndContext(
|
||||
srcFilePath: string, genFilePath: string, stmts: o.Statement[], preamble: string = '',
|
||||
emitSourceMaps: boolean = true): {sourceText: string, context: EmitterVisitorContext} {
|
||||
const converter = new _TsEmitterVisitor();
|
||||
emitSourceMaps: boolean = true,
|
||||
referenceFilter?: ReferenceFilter): {sourceText: string, context: EmitterVisitorContext} {
|
||||
const converter = new _TsEmitterVisitor(referenceFilter);
|
||||
|
||||
const ctx = EmitterVisitorContext.createRoot();
|
||||
|
||||
@ -78,10 +80,11 @@ export class TypeScriptEmitter implements OutputEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor {
|
||||
private typeExpression = 0;
|
||||
|
||||
constructor() { super(false); }
|
||||
constructor(private referenceFilter?: ReferenceFilter) { super(false); }
|
||||
|
||||
importsWithPrefixes = new Map<string, string>();
|
||||
reexports = new Map<string, {name: string, as: string}[]>();
|
||||
@ -377,6 +380,10 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
|
||||
private _visitIdentifier(
|
||||
value: o.ExternalReference, typeParams: o.Type[]|null, ctx: EmitterVisitorContext): void {
|
||||
const {name, moduleName} = value;
|
||||
if (this.referenceFilter && this.referenceFilter(value)) {
|
||||
ctx.print(null, '(null as any)');
|
||||
return;
|
||||
}
|
||||
if (moduleName) {
|
||||
let prefix = this.importsWithPrefixes.get(moduleName);
|
||||
if (prefix == null) {
|
||||
|
Reference in New Issue
Block a user