Closed
Description
TypeScript Version: 2.5.2
Code
/// input.ts
import { html, svg } from "../lit-html";
export const template = ({id = '<id>', text = '<text>'}) => html`
<div>${[
html`<p id=${id}>
${html`<b>${name}</b>)}: ${text}
</p>`
html`<p id=${id}>
<b>${name}</b>: ${text}
</p>`,
]}</div>
`;
/// transformer.ts (partial)
/* [some logic to visit nodes using ts.visitEachChild then …] */
function visitor(node) {
let substitute = node;
switch (node.kind) {
case SyntaxKind.TemplateSpan:
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
case SyntaxKind.TemplateTail:
substitute = ts.getMutableClone(node);
// borrowed from ts.updateNode (which is unexposed);
const { pos, end } = node;
ts.setTextRange(substitute, { pos, end });
}
}
/// compiler.ts (partial)
import * as ts from 'typescript';
import { transformer } from 'transformer.ts';
/* [read input.ts into sourceText as string then … ] */
const sourceFile = ts.createSourceFile(fileName, sourceText, languageVersion);
const { transformed: [transformedFile] } = ts.transform<SourceFile>(sourceFile, [transformer]);
const transformedText = ts.createPrinter().printFile(transformedFile);
/* [write transformedText to output.ts ] */
Expected behavior:
output.ts should be identical to input.ts.
Actual behavior:
/// output.ts
import { html, svg } from "../lit-html";
export const template = ({ id = "<id>", text = "<text>" }) => html `\n <div>${[
html `<p id=${id}>\n ${html `<b>${name}</b>)}: ${text}\n </p>`}`,
html `<p id=${id}>\n <b>${name}</b>: ${text}\n </p>`,
]}</div>\n `;
Additional Comments:
This is a simple way to demonstrate a much more complex scenario where I am trying to walk JSX nodes and transform them to tagged templates. The real issue I am facing is trying to figure out how to use the exposed Transformation API to create template parts that emit well-formed whitespaces, especially when dealing with newlines. I looked thoroughly but I might have missed something.
Essentially, one would expect that in the string parts of template literals, there would be some way to distinguish between a "\n"
=== `…\n…`
which is a string versus "\n"
===
`…
…`
Thanks!