Skip to content

Conversation

tsnobip
Copy link
Member

@tsnobip tsnobip commented Sep 4, 2025

Fixes #7777, #7196.

With this PR

let query = sql`
" SELECT * FROM ${table} WHERE id = ${id}`

generates

let query = Tagged_template_libJs.sql`
" SELECT * FROM ${table} WHERE id = ${id}`;

It used to generate

let query = Tagged_template_libJs.sql`\"\nSELECT * FROM ${table} WHERE id = ${id}`;

Backquoted strings are now compiled as backquoted strings in JS, but they are still concatenated with + when there are interpolations, this could be improved in a subsequent PR (for v12.1?).

@tsnobip tsnobip force-pushed the compile-to-js-template-literals branch from 8459260 to 89cb764 Compare September 4, 2025 12:20
@tsnobip tsnobip force-pushed the compile-to-js-template-literals branch from 89cb764 to a16c424 Compare September 4, 2025 12:30
Copy link

pkg-pr-new bot commented Sep 4, 2025

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@7841

@rescript/darwin-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@7841

@rescript/darwin-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@7841

@rescript/linux-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@7841

@rescript/linux-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@7841

@rescript/runtime

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@7841

@rescript/win32-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@7841

commit: a16c424

@tsnobip tsnobip requested a review from Copilot September 4, 2025 12:43
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes the compilation of tagged templates and backquoted strings in ReScript to preserve their original formatting in the generated JavaScript output. Previously, these were being mangled with unnecessary escape sequences.

  • Adds support for DBackQuotes delimiter type to preserve template literal syntax
  • Updates the string constant representation to track delimiter information instead of just unicode flag
  • Modifies the compiler pipeline to properly handle backquoted strings and tagged templates

Reviewed Changes

Copilot reviewed 46 out of 46 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/tests/src/*.mjs Test output files showing proper backquote preservation in generated JS
compiler/frontend/external_arg_spec.ml* Adds DBackQuotes delimiter type
compiler/frontend/ast_utf8_string_interp.ml Updates string interpolation handling for template literals
compiler/frontend/lam_constant.ml* Changes Const_string to use delim field instead of unicode boolean
compiler/core/*.ml Updates constant handling throughout compiler pipeline
compiler/core/js_dump.ml Adds backquote output support in JS generation

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +297 to +301
let is_template =
Ext_list.exists e.pexp_attributes (fun ({txt}, _) ->
match txt with
| "res.template" | "res.taggedTemplate" -> true
| _ -> false)
Copy link
Preview

Copilot AI Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template detection logic is duplicated in the transform_exp function but not in transform_pat. This inconsistency could lead to different behavior between expressions and patterns. Consider extracting this logic into a helper function or ensuring consistent template detection across both functions.

Copilot uses AI. Check for mistakes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is because you can't have string interpolation in pattern matching.

let is_unicode_string opt = Ext_string.equal opt Delim.escaped_j_delimiter
let is_unicode_string opt =
Ext_string.equal opt Delim.escaped_j_delimiter
|| Ext_string.equal opt Delim.escaped_back_quote_delimiter

let is_unescaped s = Ext_string.equal s Delim.unescaped_js_delimiter
Copy link
Preview

Copilot AI Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The is_unescaped function only checks for the unescaped_js_delimiter but doesn't account for the new backquote delimiter. This could lead to inconsistent behavior when processing unescaped strings with different delimiters.

Suggested change
let is_unescaped s = Ext_string.equal s Delim.unescaped_js_delimiter
let is_unescaped s =
Ext_string.equal s Delim.unescaped_js_delimiter
|| Ext_string.equal s Delim.escaped_back_quote_delimiter

Copilot uses AI. Check for mistakes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong suggestion

@tsnobip tsnobip requested review from cknitt and cristianoc September 4, 2025 13:48
Copy link
Member

@cknitt cknitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested against a large real-world project and worked fine.

@tsnobip tsnobip merged commit edf2724 into master Sep 4, 2025
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

" compiles to \" which prevent using npm:regex library
3 participants