Skip to content

Transform: unable to control or preserve whitespace in substituted template spans #18738

Closed
@SMotaal

Description

@SMotaal

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!

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: TransformsRelates to the public transform API

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions