fix(ivy): correctly resolve shorthand property declarations (#28936)

The partial evaluator in ngtsc can handle a shorthand property declaration
in the middle evaluation, but fails if evaluation starts at the shorthand
property itself. This is because evaluation starts at the ts.Identifier
of the property (the ts.Expression representing it), not the ts.Declaration
for the property.

The fix for this is to detect in TypeScriptReflectionHost when a ts.Symbol
refers to a shorthand property, and to use the ts.TypeChecker method
getShorthandAssignmentValueSymbol() to resolve the value of the assignment
instead.

FW-1089 #resolve

PR Close #28936
This commit is contained in:
Alex Rickabaugh 2019-02-22 14:11:38 -08:00 committed by Ben Lesh
parent 7b944c46d3
commit d127d05dc3
2 changed files with 24 additions and 0 deletions

View File

@ -267,6 +267,20 @@ describe('ngtsc metadata', () => {
]);
expect(value instanceof Reference).toBe(true);
});
it('should resolve shorthand properties to values', () => {
const {program} = makeProgram([
{name: 'entry.ts', contents: `const prop = 42; const target$ = {prop};`},
]);
const checker = program.getTypeChecker();
const reflectionHost = new TypeScriptReflectionHost(checker);
const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration);
const expr = result.initializer !as ts.ObjectLiteralExpression;
const prop = expr.properties[0] as ts.ShorthandPropertyAssignment;
const evaluator = new PartialEvaluator(reflectionHost, checker);
const resolved = evaluator.evaluate(prop.name);
expect(resolved).toBe(42);
});
});
function owningModuleOf(ref: Reference): string|null {

View File

@ -196,6 +196,16 @@ export class TypeScriptReflectionHost implements ReflectionHost {
* @internal
*/
protected getDeclarationOfSymbol(symbol: ts.Symbol): Declaration|null {
// If the symbol points to a ShorthandPropertyAssignment, resolve it.
if (symbol.valueDeclaration !== undefined &&
ts.isShorthandPropertyAssignment(symbol.valueDeclaration)) {
const shorthandSymbol =
this.checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
if (shorthandSymbol === undefined) {
return null;
}
return this.getDeclarationOfSymbol(shorthandSymbol);
}
let viaModule: string|null = null;
// Look through the Symbol's immediate declarations, and see if any of them are import-type
// statements.