fix(ivy): support late-initialized variables in ngcc/ngtsc (#26236)

In some formats variables are declared as `var` or `let` and only
assigned a value later in the code.

The ngtsc resolver still needs to be able to resolve this value,
so the host now provides a `host.getVariableValue(declaration)`
method that can do this resolution based on the format.

The hosts make some assumptions about the layout of the
code, so they may only work in the constrained scenarios that
ngcc expects.

PR Close #26236
This commit is contained in:
Pete Bacon Darwin
2018-10-01 11:10:55 +01:00
committed by Jason Aden
parent 9320ec0f43
commit 13cdd13511
5 changed files with 114 additions and 2 deletions

View File

@ -419,4 +419,16 @@ export interface ReflectionHost {
* is not a class or has an unknown number of type parameters.
*/
getGenericArityOfClass(clazz: ts.Declaration): number|null;
/**
* Find the assigned value of a variable declaration.
*
* Normally this will be the initializer of the declaration, but where the variable is
* not a `const` we may need to look elsewhere for the variable's value.
*
* @param declaration a TypeScript variable declaration, whose value we want.
* @returns the value of the variable, as a TypeScript expression node, or `undefined`
* if the value cannot be computed.
*/
getVariableValue(declaration: ts.VariableDeclaration): ts.Expression|null;
}

View File

@ -166,6 +166,10 @@ export class TypeScriptReflectionHost implements ReflectionHost {
return clazz.typeParameters !== undefined ? clazz.typeParameters.length : 0;
}
getVariableValue(declaration: ts.VariableDeclaration): ts.Expression|null {
return declaration.initializer || null;
}
/**
* Resolve a `ts.Symbol` to its declaration, keeping track of the `viaModule` along the way.
*

View File

@ -454,8 +454,9 @@ class StaticInterpreter {
}
private visitVariableDeclaration(node: ts.VariableDeclaration, context: Context): ResolvedValue {
if (node.initializer !== undefined) {
return this.visitExpression(node.initializer, context);
const value = this.host.getVariableValue(node);
if (value !== null) {
return this.visitExpression(value, context);
} else if (isVariableDeclarationDeclared(node)) {
return this.getReference(node, context);
} else {