Skip to content

Add %raw syntax for fixed external arguments - #8609

Closed
cknitt wants to merge 4 commits into
rescript-lang:masterfrom
cknitt:codex/raw-external-arguments
Closed

cknitt wants to merge 4 commits into
rescript-lang:masterfrom
cknitt:codex/raw-external-arguments

Conversation

@cknitt

@cknitt cknitt commented Sep 3, 2026

Copy link
Copy Markdown
Member

Summary

Introduce a dedicated parsetree representation and new syntax for fixed external arguments.

Previously, fixed values were expressed using an @as attribute on a wildcard type:

@val
external unsafeAddStyle: (@as(json`{}`) _, t, {..}) => t = "Object.assign"

They can now be written using the familiar %raw extension syntax:

@val
external unsafeAddStyle: (%raw("{}"), t, {..}) => t = "Object.assign"

The %raw payload must be a string containing a JavaScript literal. Non-interpolated template strings are also supported, which is convenient for JavaScript string values:

external createElement: (%raw(`"img"`), document) => element = "createElement"

Compatibility

Existing fixed-value forms continue to parse:

@as(json`{}`) _
@as("img") _
@as(1) _

They now:

  • emit a deprecation warning;
  • normalize to the dedicated fixed-argument parsetree node;
  • format automatically to the corresponding %raw(...) syntax.

The json tag no longer has a special string-literal representation in the AST. Outside this compatibility path, json templates behave like ordinary tagged template strings.

Implementation

Fixed external arguments are represented explicitly as Parg_fixed, containing the raw JavaScript source and argument metadata. The representation is handled across AST traversal, mapping, analysis, type checking, external processing, and printing.

The frozen v0 parsetree remains unchanged. The existing AST mapping bridge converts fixed arguments to and from a compatible v0 representation.

Testing

Added and updated coverage for:

  • parser and formatter behavior;
  • legacy syntax migration and deprecation warnings;
  • %raw string and template-string payloads;
  • invalid payloads and invalid positions;
  • v0 parsetree round trips;
  • analysis features;
  • generated JavaScript and runtime behavior.

make test, syntax tests, and syntax round-trip tests pass.

@codecov

codecov Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.91803% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.98%. Comparing base (bc2e0e1) to head (d6388f3).

Files with missing lines Patch % Lines
compiler/frontend/ast_external_process.ml 76.66% 7 Missing ⚠️
compiler/ml/printast.ml 0.00% 6 Missing ⚠️
compiler/syntax/src/res_core.ml 86.04% 6 Missing ⚠️
compiler/frontend/ast_attributes.ml 40.00% 3 Missing ⚠️
compiler/ml/ast_payload.ml 89.65% 3 Missing ⚠️
compiler/core/js_dump.ml 33.33% 2 Missing ⚠️
compiler/ml/ast_mapper_from0.ml 87.50% 2 Missing ⚠️
compiler/ml/pprintast.ml 83.33% 2 Missing ⚠️
compiler/ml/typecore.ml 50.00% 2 Missing ⚠️
tests/ounit_tests/ounit_string_literal_tests.ml 95.12% 2 Missing ⚠️
... and 11 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8609      +/-   ##
==========================================
- Coverage   80.99%   80.98%   -0.02%     
==========================================
  Files         453      453              
  Lines       62989    63112     +123     
==========================================
+ Hits        51020    51113      +93     
- Misses      11969    11999      +30     
Files with missing lines Coverage Δ
analysis/src/dump_ast.ml 43.82% <ø> (+0.18%) ⬆️
compiler/core/j.ml 100.00% <ø> (ø)
compiler/core/js_record_fold.ml 93.03% <100.00%> (ø)
compiler/core/js_record_iter.ml 100.00% <100.00%> (ø)
compiler/core/js_record_map.ml 100.00% <100.00%> (ø)
compiler/core/lam_compile_const.ml 93.54% <100.00%> (-0.40%) ⬇️
compiler/frontend/ast_config.ml 87.87% <ø> (-0.36%) ⬇️
compiler/frontend/ast_derive_projector.ml 90.16% <100.00%> (ø)
compiler/frontend/ast_exp_extension.ml 100.00% <ø> (ø)
compiler/frontend/ast_exp_handle_external.ml 82.50% <100.00%> (ø)
... and 35 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new

pkg-pr-new Bot commented Sep 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

rescript

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

@rescript/belt

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

@rescript/darwin-arm64

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

@rescript/darwin-x64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

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

@rescript/win32-x64

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

commit: 29d80dd

@cknitt
cknitt force-pushed the codex/raw-external-arguments branch 2 times, most recently from b936a7e to 18d5799 Compare October 15, 2026 04:22
cknitt and others added 4 commits October 15, 2026 18:31
Signed-off-by: Christoph Knittel <ck@cca.io>
Signed-off-by: Christoph Knittel <ck@cca.io>
Signed-off-by: Christoph Knittel <ck@cca.io>
Keep comments around and inside fixed arguments, spell integer payloads
as plain JavaScript integers, require %raw payloads to be exactly one
literal, reject optional fixed arguments clearly, and read legacy @as
payloads the same way in the parser, the frontend and the v0 bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

Superseded by the stack #8875 (remove Pconst_json and represent fixed external arguments in the parsetree) and #8876 (provisional %raw syntax for fixed external arguments), so the syntax can be discussed separately.

@cknitt cknitt closed this Oct 16, 2026
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.

1 participant