mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 10:46:28 -05:00
WIP: try to add snippet escaping in emitter
This commit is contained in:
@@ -911,6 +911,9 @@ namespace ts {
|
||||
const parenthesizer = factory.parenthesizer;
|
||||
const emitBinaryExpression = createEmitBinaryExpression();
|
||||
|
||||
// Snippets
|
||||
let inSnippet = false;
|
||||
|
||||
reset();
|
||||
return {
|
||||
// public API
|
||||
@@ -1283,8 +1286,9 @@ namespace ts {
|
||||
currentParenthesizerRule = undefined;
|
||||
}
|
||||
|
||||
function pipelineEmitWithHintWorker(hint: EmitHint, node: Node, allowSnippets = true): void {
|
||||
if (allowSnippets) {
|
||||
// >> TODO: remove allowSnippets
|
||||
function pipelineEmitWithHintWorker(hint: EmitHint, node: Node, _allowSnippets = true): void {
|
||||
if (!inSnippet) {
|
||||
const snippet = getSnippetElement(node);
|
||||
if (snippet) {
|
||||
return emitSnippetNode(hint, node, snippet);
|
||||
@@ -1877,14 +1881,19 @@ namespace ts {
|
||||
const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
|
||||
if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
|
||||
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
|
||||
writeLiteral(text);
|
||||
writeLiteral(inSnippet ? escapeSnippetText(text) : text);
|
||||
}
|
||||
else {
|
||||
// Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals
|
||||
writeStringLiteral(text);
|
||||
writeStringLiteral(inSnippet ? escapeSnippetText(text) : text);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move this
|
||||
function escapeSnippetText(text: string): string {
|
||||
return text.replace(/\$/gm, "\\$");
|
||||
}
|
||||
|
||||
// SyntaxKind.UnparsedSource
|
||||
// SyntaxKind.UnparsedPrepend
|
||||
function emitUnparsedSourceOrPrepend(unparsed: UnparsedSource | UnparsedPrepend) {
|
||||
@@ -1935,12 +1944,16 @@ namespace ts {
|
||||
//
|
||||
|
||||
function emitSnippetNode(hint: EmitHint, node: Node, snippet: SnippetElement) {
|
||||
inSnippet = true;
|
||||
switch (snippet.kind) {
|
||||
case SnippetKind.Placeholder:
|
||||
return emitPlaceholder(hint, node, snippet);
|
||||
emitPlaceholder(hint, node, snippet);
|
||||
break;
|
||||
case SnippetKind.TabStop:
|
||||
return emitTabStop(snippet);
|
||||
emitTabStop(snippet);
|
||||
break;
|
||||
}
|
||||
inSnippet = false;
|
||||
}
|
||||
|
||||
function emitPlaceholder(hint: EmitHint, node: Node, snippet: Placeholder) {
|
||||
@@ -1960,7 +1973,8 @@ namespace ts {
|
||||
|
||||
function emitIdentifier(node: Identifier) {
|
||||
const writeText = node.symbol ? writeSymbol : write;
|
||||
writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
|
||||
const text = getTextOfNode(node, /*includeTrivia*/ false);
|
||||
writeText(inSnippet ? escapeSnippetText(text) : text, node.symbol);
|
||||
emitList(node, node.typeArguments, ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments
|
||||
}
|
||||
|
||||
@@ -1970,7 +1984,8 @@ namespace ts {
|
||||
|
||||
function emitPrivateIdentifier(node: PrivateIdentifier) {
|
||||
const writeText = node.symbol ? writeSymbol : write;
|
||||
writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
|
||||
const text = getTextOfNode(node, /*includeTrivia*/ false);
|
||||
writeText(inSnippet ? escapeSnippetText(text) : text, node.symbol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,36 @@
|
||||
/* eslint-disable no-fallthrough */
|
||||
/* @internal */
|
||||
namespace ts.snippets {
|
||||
// interface SnippetWriter extends EmitTextWriter, PrintHandlers {}
|
||||
|
||||
// function createSnippetWriter(newLine: string): SnippetWriter {
|
||||
// const substituteNode = (hint: EmitHint, node: Node) => {
|
||||
// switch (hint) {
|
||||
// case EmitHint.IdentifierName:
|
||||
// // >> TODO: do escaping here
|
||||
// return node;
|
||||
// const substituteNode = (_hint: EmitHint, node: Node) => {
|
||||
// switch (node.kind) {
|
||||
// // Comments:
|
||||
// // TODO: doesn't work because comments are `TextRanges` with a syntax kind, but are not nodes.
|
||||
// // case SyntaxKind.SingleLineCommentTrivia:
|
||||
// // case SyntaxKind.MultiLineCommentTrivia:
|
||||
// // return escapeTrivia(node);
|
||||
// // >> comments are emitted in previous phase
|
||||
// // String-like literals:
|
||||
// case SyntaxKind.StringLiteral: // >> emitLiteral
|
||||
// return escapeLiteralLikeNode(node as StringLiteral);
|
||||
// case SyntaxKind.RegularExpressionLiteral: // >> emitLiteral
|
||||
// return escapeLiteralLikeNode(node as RegularExpressionLiteral);
|
||||
// case SyntaxKind.NoSubstitutionTemplateLiteral: // >> emitLiteral
|
||||
// // Has .rawText but also .text
|
||||
// // Templates:
|
||||
// // >> .rawText
|
||||
// case SyntaxKind.TemplateHead: // >> emitLiteral
|
||||
// case SyntaxKind.TemplateMiddle: // >> emitLiteral
|
||||
// case SyntaxKind.TemplateTail: // >> emitLiteral
|
||||
// // Identifiers:
|
||||
// case SyntaxKind.Identifier: // >> emitIdentifier
|
||||
// case SyntaxKind.PrivateIdentifier: // >> emitPrivateIdentifier
|
||||
// // Other:
|
||||
// // >> TODO: JSX? JSDoc?
|
||||
|
||||
// return undefined;
|
||||
// }
|
||||
// return node;
|
||||
// };
|
||||
@@ -20,4 +43,14 @@ namespace ts.snippets {
|
||||
// substituteNode,
|
||||
// };
|
||||
// }
|
||||
|
||||
// function escapeLiteralLikeNode<T extends LiteralLikeNode>(node: T): T {
|
||||
// const copy = getSynthesizedDeepClone(node);
|
||||
// copy.text = escapeSnippetText(node.text);
|
||||
// return copy;
|
||||
// }
|
||||
|
||||
// function escapeSnippetText(text: string): string {
|
||||
// return text.replace(/\$/gm, "\\$");
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user