Fix template string refactoring and nodeFactory bug#44313
Fix template string refactoring and nodeFactory bug#44313elibarzilay merged 1 commit intomicrosoft:mainfrom
Conversation
e2da2bb to
d069dcf
Compare
QuestionThis is using |
|
ping @rbuckton |
tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapeSequences.ts
Outdated
Show resolved
Hide resolved
src/compiler/factory/nodeFactory.ts
Outdated
| // @api | ||
| function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { | ||
| const node = createBaseToken<TemplateLiteralLikeNode>(kind); | ||
| rawText ??= JSON.stringify(text).slice(1,-1).replace(/\\.|\$/g, s => |
There was a problem hiding this comment.
I don't think we should try to synthesize rawText here. Generally when rawText is undefined we intend to pull the "raw" version of the template literal from the source file during emit. rawText was added to allow API consumers to pass their own "raw" text, and in those cases it goes through createTemplateLiteralLikeNodeChecked which verifies that the "cooked" text matches the supplied "raw" text.
If someone were to pass the string "\t " (byte sequence 5c 74 09) for text, this would generate a "raw" text of "\t\t". There's no way to be 100% sure what the user intended, so its better to be explicit.
I think the issue is actually in the implementation of the refactor, which should be reading the raw source text of the string literal rather than node.text.
There was a problem hiding this comment.
Its also important that rawText remains undefined for our tagged template transform to accurately get the actual raw text from the source file for non-user-created nodes:
TypeScript/src/compiler/transformers/taggedTemplate.ts
Lines 78 to 84 in eb3645f
30d1f7c to
ee7b39d
Compare
createTemplateHead*|
|
||
| let token = rawTextScanner.scan(); | ||
| if (token === SyntaxKind.CloseBracketToken) { | ||
| if (token === SyntaxKind.CloseBraceToken) { |
There was a problem hiding this comment.
Obvious typo I wish I'd caught sooner 😔. Good catch.
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. Some `||` -> `??`. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Related to microsoft#44313 and microsoft#40625.
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. Some `||` -> `??`. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Related to microsoft#44313 and microsoft#40625.
rbuckton
left a comment
There was a problem hiding this comment.
A few minor nits but this looks good.
93acbe8 to
8e01e23
Compare
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. One `||` -> `??` change. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Related to microsoft#44313 and microsoft#40625.
Instead of letting `createTemplate*` generate a broken raw string from
the cooked one, grab the source code for it.
Also, add a missing bit to `\`-quote `$`s. As the comment in the code
says, it could just `\`-quote `${` since other `$`s are valid, but I
think that it's less confusing to always quote $s (but the change is in
the comment if minimalism is preferred).
Also, a small-but-confusing bug in `getCookedText()`.
Many tests for all of this.
Fixes microsoft#40625
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. One `||` -> `??` change. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Added test. Related to microsoft#44313 and microsoft#40625.
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. One `||` -> `??` change. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Added test. Related to microsoft#44313 and microsoft#40625.
1. `getRawLiteral()`: barf if `currentSourceFile` is missing, since if it is, then the following `getSourceTextOfNodeFromSourceFile` will return a bogus `""`. 2. One `||` -> `??` change. 3. `backtickQuoteEscapedCharsRegExp`: escape the usual control characters except for a simple LF. This code does get used to generate backtick strings when `rawText` is not given, and not escaping things like TAB characters can get mangled by editor settings. Worse, not escaping a CRLF and putting it verbatim in sthe string source will interpret it as LF, so add a special case for escaping these as `\r\n`. Added test. Related to #44313 and #40625.
Fix template string refactoring and nodeFactory bug
Instead of letting
createTemplate*generate a broken raw string fromthe cooked one, grab the source code for it.
Also, add a missing bit to
\-quote$s. As the comment in the codesays, it could just
\-quote${since other$s are valid, but Ithink that it's less confusing to always quote $s (but the change is in
the comment if minimalism is preferred).
Also, a small-but-confusing bug in
getCookedText().Many tests for all of this.
Fixes #40625