Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions compiler/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,51 @@ let rewrite_underscore_apply expr =
}
| _ -> expr

(* For pipe RHS: (__x) => f(__x, a, b) -----> f(a, b)
Omits the first __x argument since the piped value fills that position *)
let rewrite_underscore_apply_in_pipe expr =
match expr.pexp_desc with
| Pexp_fun
{
arg_label = Nolabel;
default = None;
lhs = {ppat_desc = Ppat_var {txt = "__x"}};
rhs = {pexp_desc = Pexp_apply {funct = call_expr; args}} as e;
} -> (
match args with
| (Nolabel, {pexp_desc = Pexp_ident {txt = Longident.Lident "__x"}})
:: rest_args ->
(* First arg is __x, skip it and convert remaining __x to _ *)
let new_args =
List.map
(fun arg ->
match arg with
| ( lbl,
({
pexp_desc = Pexp_ident ({txt = Longident.Lident "__x"} as lid);
} as arg_expr) ) ->
( lbl,
{
arg_expr with
pexp_desc = Pexp_ident {lid with txt = Longident.Lident "_"};
} )
| arg -> arg)
rest_args
in
{
e with
pexp_desc =
Pexp_apply
{
funct = call_expr;
args = new_args;
partial = false;
transformed_jsx = false;
};
}
| _ -> rewrite_underscore_apply expr)
| _ -> expr

type fun_param_kind =
| Parameter of {
attrs: Parsetree.attributes;
Expand Down
3 changes: 3 additions & 0 deletions compiler/syntax/src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ val is_single_pipe_expr : Parsetree.expression -> bool
(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
val rewrite_underscore_apply : Parsetree.expression -> Parsetree.expression

val rewrite_underscore_apply_in_pipe :
Parsetree.expression -> Parsetree.expression

(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
val is_underscore_apply_sugar : Parsetree.expression -> bool

Expand Down
5 changes: 5 additions & 0 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3985,6 +3985,11 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
->
let lhs_has_comment_below = has_comment_below cmt_tbl lhs.pexp_loc in
let lhs_doc = print_operand ~is_lhs:true ~is_multiline:false lhs op in
(* For pipe RHS, use pipe-specific rewrite to omit redundant first underscore *)
let rhs =
if op = "->" then ParsetreeViewer.rewrite_underscore_apply_in_pipe rhs
else rhs
in
let rhs_doc = print_operand ~is_lhs:false ~is_multiline:false rhs op in
Doc.group
(Doc.concat
Expand Down
10 changes: 9 additions & 1 deletion scripts/test_syntax.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ if [[ $ROUNDTRIP_TEST = 1 ]]; then
mkdir -p temp/$(dirname $file)
sexpAst1=temp/$file.sexp
sexpAst2=temp/$file.2.sexp
sexpAst3=temp/$file.3.sexp
rescript1=temp/$file.res
rescript2=temp/$file.2.res

Expand All @@ -89,14 +90,21 @@ if [[ $ROUNDTRIP_TEST = 1 ]]; then
*.resi ) resIntf=-interface ;;
esac

# First pass: original file -> AST1 and text1
$DUNE_BIN_DIR/res_parser $resIntf -print sexp $file > $sexpAst1
$DUNE_BIN_DIR/res_parser $resIntf -print res $file > $rescript1

# Second pass: text1 -> AST2 and text2
$DUNE_BIN_DIR/res_parser $resIntf -print sexp $rescript1 > $sexpAst2
$DUNE_BIN_DIR/res_parser $resIntf -print res $rescript1 > $rescript2

diff --unified $sexpAst1 $sexpAst2
# Third pass: text2 -> AST3 (to check idempotency after normalization)
$DUNE_BIN_DIR/res_parser $resIntf -print sexp $rescript2 > $sexpAst3

# Check AST idempotency: AST2 should equal AST3 (allows AST1 != AST2 for canonicalization)
diff --unified $sexpAst2 $sexpAst3
[[ "$?" = 1 ]] && echo 1 > $roundtripTestsResult
# Check text idempotency: text1 should equal text2
diff --unified $rescript1 $rescript2
[[ "$?" = 1 ]] && echo 1 > $roundtripTestsResult
} & maybeWait
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let nested2 = (x, y, z) => List.length(_)

let l = [1, 2, 3]->List.map(i => i + 1, _)->List.filter(i => i > 0, _)

let l = (i => i + 1)->List.map(_, [1, 2, 3])
let l = (i => i + 1)->List.map([1, 2, 3])

let x = List.length(_)

Expand Down Expand Up @@ -52,8 +52,8 @@ f(a, b, _)[ix] = 2

getDirector(a, b, _).name = "Steve"

filterNone->Array.get(_, 0)
filterNone->Array.get(_, 0)
filterNone->Array.get(0)
filterNone->Array.get(0)
Array.get(_, 0)
1 + Array.get(_, 0)
Array.get(_, 1) + Array.get(_, 0)
Expand Down
Loading