From 8a986d4642a82734cda9624934ff96da86e42aa9 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Mon, 9 Jul 2018 11:39:15 -0700 Subject: [PATCH] feat(ivy): statically resolve template expressions (#24862) This commit adds support for template substitution expressions for ngtsc static resolution. PR Close #24862 --- .../src/ngtsc/metadata/src/resolver.ts | 18 ++++++++++++++++++ .../src/ngtsc/metadata/test/resolver_spec.ts | 3 +++ packages/compiler-cli/test/ngtsc/ngtsc_spec.ts | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts index 9c3f7891f7..a63ec59081 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts @@ -258,6 +258,8 @@ class StaticInterpreter { return node.text; } else if (ts.isNoSubstitutionTemplateLiteral(node)) { return node.text; + } else if (ts.isTemplateExpression(node)) { + return this.visitTemplateExpression(node, context); } else if (ts.isNumericLiteral(node)) { return parseFloat(node.text); } else if (ts.isObjectLiteralExpression(node)) { @@ -362,6 +364,22 @@ class StaticInterpreter { 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 { let absoluteModuleName = context.absoluteModuleName; if (symbol.declarations !== undefined && symbol.declarations.length > 0) { diff --git a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts b/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts index 7a41ad3595..740dd1ea0c 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts @@ -249,4 +249,7 @@ describe('ngtsc metadata', () => { 'obj.fn("test")')) .toEqual('test'); }); + + it('template expressions work', + () => { expect(evaluate('const a = 2, b = 4;', '`1${a}3${b}5`')).toEqual('12345'); }); }); diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 3046f5dbc6..7ad4cf2ffa 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -345,7 +345,7 @@ describe('ngtsc behavioral tests', () => { expect(dtsContents).toContain('i0.ɵNgModuleDef'); }); - 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(); write(`test.ts`, ` import {NgModule} from '@angular/core';