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:
parent
e346c3c2f2
commit
8a986d4642
|
@ -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) {
|
||||||
|
|
|
@ -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'); });
|
||||||
});
|
});
|
||||||
|
|
|
@ -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';
|
||||||
|
|
Loading…
Reference in New Issue