feat(ivy): statically resolve template expressions (#24862)

This commit adds support for template substitution expressions for
ngtsc static resolution.

PR Close #24862
This commit is contained in:
Alex Rickabaugh 2018-07-09 11:39:15 -07:00 committed by Victor Berchet
parent e346c3c2f2
commit 8a986d4642
3 changed files with 22 additions and 1 deletions

View File

@ -258,6 +258,8 @@ class StaticInterpreter {
return node.text; return node.text;
} else if (ts.isNoSubstitutionTemplateLiteral(node)) { } else if (ts.isNoSubstitutionTemplateLiteral(node)) {
return node.text; return node.text;
} else if (ts.isTemplateExpression(node)) {
return this.visitTemplateExpression(node, context);
} else if (ts.isNumericLiteral(node)) { } else if (ts.isNumericLiteral(node)) {
return parseFloat(node.text); return parseFloat(node.text);
} else if (ts.isObjectLiteralExpression(node)) { } else if (ts.isObjectLiteralExpression(node)) {
@ -362,6 +364,22 @@ class StaticInterpreter {
return this.visitSymbol(symbol, context); return this.visitSymbol(symbol, context);
} }
private visitTemplateExpression(node: ts.TemplateExpression, context: Context): ResolvedValue {
const pieces: string[] = [node.head.text];
for (let i = 0; i < node.templateSpans.length; i++) {
const span = node.templateSpans[i];
const value = this.visit(span.expression, context);
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ||
value == null) {
pieces.push(`${value}`);
} else {
return DYNAMIC_VALUE;
}
pieces.push(span.literal.text);
}
return pieces.join('');
}
private visitSymbol(symbol: ts.Symbol, context: Context): ResolvedValue { private visitSymbol(symbol: ts.Symbol, context: Context): ResolvedValue {
let absoluteModuleName = context.absoluteModuleName; let absoluteModuleName = context.absoluteModuleName;
if (symbol.declarations !== undefined && symbol.declarations.length > 0) { if (symbol.declarations !== undefined && symbol.declarations.length > 0) {

View File

@ -249,4 +249,7 @@ describe('ngtsc metadata', () => {
'obj.fn("test")')) 'obj.fn("test")'))
.toEqual('test'); .toEqual('test');
}); });
it('template expressions work',
() => { expect(evaluate('const a = 2, b = 4;', '`1${a}3${b}5`')).toEqual('12345'); });
}); });

View File

@ -345,7 +345,7 @@ describe('ngtsc behavioral tests', () => {
expect(dtsContents).toContain('i0.ɵNgModuleDef<TestModule, [TestPipe,TestCmp], [], []>'); expect(dtsContents).toContain('i0.ɵNgModuleDef<TestModule, [TestPipe,TestCmp], [], []>');
}); });
it('should unwrap a ModuleWithProviders functoin if a generic type is provided for it', () => { it('should unwrap a ModuleWithProviders function if a generic type is provided for it', () => {
writeConfig(); writeConfig();
write(`test.ts`, ` write(`test.ts`, `
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';