Skip to content

Commit 7e17118

Browse files
authored
Remove parser modes (#8610)
* Refactor constructor arity in parsetree Signed-off-by: Christoph Knittel <ck@cca.io> * Remove obsolete parser printer flag Signed-off-by: Christoph Knittel <ck@cca.io> * Share constructor pattern argument parsing Signed-off-by: Christoph Knittel <ck@cca.io> * Share constructor argument printing Signed-off-by: Christoph Knittel <ck@cca.io> * Centralize AST0 constructor argument bridging Signed-off-by: Christoph Knittel <ck@cca.io> * Localize legacy explicit arity handling Signed-off-by: Christoph Knittel <ck@cca.io> * Use plural names for constructor source arguments Signed-off-by: Christoph Knittel <ck@cca.io> * Add constructor arity changelog entry Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve fresh AST0 constructor arity Signed-off-by: Christoph Knittel <ck@cca.io> * Partition polymorphic variant argument comments Signed-off-by: Christoph Knittel <ck@cca.io> * Fix AST0 constructor payload locations and printing Signed-off-by: Christoph Knittel <ck@cca.io> * Bump compiled artifact versions for constructor AST changes Signed-off-by: Christoph Knittel <ck@cca.io> * Deduplicate AST0 bridge marker removal Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve polymorphic variant payload spans across AST0 Signed-off-by: Christoph Knittel <ck@cca.io> * Retain constructor signature help between arguments Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve constructor compatibility without parser modes Apply the normalization approach proposed by @cristianoc in PR #8610. Keep source argument lists for printing and resolve semantic grouping after constructor disambiguation, without legacy PPX marker handling in the type checker or printer. Signed-off-by: Christoph Knittel <ck@cca.io> * Remove redundant single-tuple AST0 bridge marker Signed-off-by: Christoph Knittel <ck@cca.io> * Revert unnecessary constructor syntax migrations Signed-off-by: Christoph Knittel <ck@cca.io> * Simplify constructor bridge metadata handling and assertions Signed-off-by: Christoph Knittel <ck@cca.io> * Clarify constructor argument naming and simplify traversal Signed-off-by: Christoph Knittel <ck@cca.io> * Rename constructor argument compatibility fixture Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve constructor argument-list locations explicitly Signed-off-by: Christoph Knittel <ck@cca.io> * Reuse argument-list locations in parsing and type checking Signed-off-by: Christoph Knittel <ck@cca.io> * Use argument-list boundaries for constructor signature help Signed-off-by: Christoph Knittel <ck@cca.io> * Accept located constructor arguments in AST helpers Signed-off-by: Christoph Knittel <ck@cca.io> * Separate constructor argument tests from AST0 bridge coverage Signed-off-by: Christoph Knittel <ck@cca.io> * Document the constructor argument AST0 bridge contract Signed-off-by: Christoph Knittel <ck@cca.io> * Use explicit locations at constructor helper call sites Signed-off-by: Christoph Knittel <ck@cca.io> * Normalize constructor tuple paths in completion Signed-off-by: Christoph Knittel <ck@cca.io> * Select constructor tuple parameters in signature help Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve constructor source arity in completion paths Signed-off-by: Christoph Knittel <ck@cca.io> * Use shared argument traversal for constructor completion gaps Signed-off-by: Christoph Knittel <ck@cca.io> * Reuse resolved inline-record constructor fields in completion Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve list constructor attributes on the AST0 wire Signed-off-by: Christoph Knittel <ck@cca.io> * Simplify AST0 argument tuple callbacks Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve attributed list payload tuples across AST0 conversions Signed-off-by: Christoph Knittel <ck@cca.io> * Adapt constructor tag helper to argument lists Signed-off-by: Christoph Knittel <ck@cca.io> * Normalize constructor payload grouping in completion paths Signed-off-by: Christoph Knittel <ck@cca.io> * Keep unary tuple signature help on its only parameter Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve attributes on marked polymorphic variant type tuples Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve attributed payloads in shared constructor decoding Signed-off-by: Christoph Knittel <ck@cca.io> * Complete between existing constructor arguments Signed-off-by: Christoph Knittel <ck@cca.io> * Fix payload completion for qualified constructor patterns Signed-off-by: Christoph Knittel <ck@cca.io> * Preserve nested constructor payload completion Signed-off-by: Christoph Knittel <ck@cca.io> --------- Signed-off-by: Christoph Knittel <ck@cca.io>
1 parent 5357fe4 commit 7e17118

102 files changed

Lines changed: 4525 additions & 1226 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
- Fix escaped backticks and interpolation openers in backquoted `%raw`, `%ffi`, and `%re` payloads leaking into emitted JavaScript. https://github.com/rescript-lang/rescript/pull/8630
4040
- Fix the side-effect analysis treating bigint exponentiation and bounds-checked array and string reads as pure, which let dead-code elimination drop an unused one that throws: `let _ = 2n ** -1n` no longer raised. https://github.com/rescript-lang/rescript/pull/8617
4141
- Preserve record field `@as` annotations when formatting object types containing spreads. https://github.com/rescript-lang/rescript/pull/8619
42+
- Fix record-field completion inside constructor tuple payloads and for their destructured bindings, including both supported tuple spellings and polymorphic variants. https://github.com/rescript-lang/rescript/pull/8610
43+
- Limit constructor signature help to the argument parentheses, excluding whitespace and comments between the constructor name and its arguments, and keep unary tuple payloads on parameter zero. https://github.com/rescript-lang/rescript/pull/8610
4244
- Fix excessive parentheses and indentation in function assignments to refs, align record and array assignment formatting across refs and fields, and preserve function return-type parentheses and consistent JSX fragment layout in callbacks. https://github.com/rescript-lang/rescript/pull/8611
4345
- Report an error instead of crashing when an integer in a variant constructor's `@as` annotation exceeds the compiler's integer range. https://github.com/rescript-lang/rescript/pull/8619
4446
- Warn about an `@as` on a record field whose payload does not name the field, such as `@as(42)`. It renamed nothing and was silently accepted. https://github.com/rescript-lang/rescript/pull/8619
@@ -82,6 +84,7 @@
8284
- Record a record field's `@as` rename on the declaration instead of re-reading the attribute, so every place that needs the runtime name reads one field. https://github.com/rescript-lang/rescript/pull/8619
8385
- Record a variant constructor's `@as` tag on the declaration instead of re-interpreting its attributes, keeping the source spelling for printing. https://github.com/rescript-lang/rescript/pull/8619
8486
- Optimization passes now return the term they were given when they change nothing, rather than rebuilding an identical one. https://github.com/rescript-lang/rescript/pull/8620
87+
- Remove separate parser modes for printing and type checking by preserving syntactic constructor arguments and their source locations in the parsetree and resolving their semantic grouping during type checking. Existing constructor spellings and legacy PPX output remain supported. https://github.com/rescript-lang/rescript/pull/8610
8588
- Merge the duplicate Lam intermediate representation into Lambda, removing the conversion layer and obsolete supporting infrastructure. Lambda is now a single private, normalized representation, with generated JavaScript remaining semantically unchanged. https://github.com/rescript-lang/rescript/pull/8608
8689
- Add genType and source map controls and output to the developer playground. https://github.com/rescript-lang/rescript/pull/8448
8790
- Rework the object-type representation end to end: object rows are plain field chains carrying a per-field mutability state (no phantom setter members), object literals are typed directly and property access and assignment are first-class AST and Lambda nodes shared between the Lambda and JS pipelines, and dead class-system remnants (the field-presence lattice, the class-abbreviation memo on object types, method-send typing) are removed. https://github.com/rescript-lang/rescript/pull/8597

analysis/reanalyze/src/annotation.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ let rec get_attribute_payload check_text (attributes : Typedtree.attributes) =
3030
_;
3131
} ->
3232
Some (BoolPayload (s = "true"))
33-
| {pexp_desc = Pexp_construct ({txt = Longident.Lident "[]"}, None)} ->
33+
| {pexp_desc = Pexp_construct ({txt = Longident.Lident "[]"}, {txt = []})}
34+
->
3435
None
35-
| {pexp_desc = Pexp_construct ({txt = Longident.Lident "::"}, Some e)} ->
36-
from_expr e
36+
| {
37+
pexp_desc =
38+
Pexp_construct ({txt = Longident.Lident "::"}, {txt = [head; tail]});
39+
} ->
40+
from_expr {expr with pexp_desc = Pexp_tuple [head; tail]}
3741
| {pexp_desc = Pexp_construct ({txt}, _); _} ->
3842
Some (ConstructPayload (txt |> Longident.flatten |> String.concat "."))
3943
| {pexp_desc = Pexp_tuple exprs | Pexp_array exprs} ->

analysis/src/codemod.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ let transform_opt ~source ~pos ~debug ~typ ~hint =
1313
| AddMissingCases -> (
1414
let source = "let " ^ hint ^ " = ()" in
1515
let {Res_driver.parsetree = hint_structure} =
16-
Res_driver.parse_implementation_from_source ~for_printer:false
17-
~display_filename:"<none>" ~source
16+
Res_driver.parse_implementation_from_source ~display_filename:"<none>"
17+
~source
1818
in
1919
match hint_structure with
2020
| [{pstr_desc = Pstr_value (_, [{pvb_pat = pattern}])}] -> (

analysis/src/commands.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,7 @@ let format ~source ~kind_file =
304304
match kind_file with
305305
| Files.Res -> (
306306
let {Res_driver.parsetree = structure; comments; diagnostics} =
307-
Res_driver.parsing_engine.parse_implementation_from_source
308-
~for_printer:true ~source
307+
Res_driver.parsing_engine.parse_implementation_from_source ~source
309308
in
310309
match List.length diagnostics > 0 with
311310
| true -> Error "Document has syntax errors"
@@ -314,8 +313,7 @@ let format ~source ~kind_file =
314313
)
315314
| Resi -> (
316315
let {Res_driver.parsetree = signature; comments; diagnostics} =
317-
Res_driver.parsing_engine.parse_interface_from_source ~for_printer:true
318-
~source
316+
Res_driver.parsing_engine.parse_interface_from_source ~source
319317
in
320318
match List.length diagnostics > 0 with
321319
| true -> Error "Document has syntax errors"

analysis/src/completion_expressions.ml

Lines changed: 44 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ let is_expr_hole exp =
55
| Pexp_extension ({txt = "rescript.exprhole"}, _) -> true
66
| _ -> false
77

8-
let is_expr_tuple expr =
9-
match expr.Parsetree.pexp_desc with
10-
| Pexp_tuple _ -> true
11-
| _ -> false
12-
138
let rec traverse_expr (exp : Parsetree.expression) ~expr_path ~pos
149
~first_char_before_cursor_no_white =
1510
let loc_has_cursor loc = loc |> Cursor_position.loc_has_cursor ~pos in
@@ -24,9 +19,10 @@ let rec traverse_expr (exp : Parsetree.expression) ~expr_path ~pos
2419
(txt, [Completable.NRecordBody {seen_fields = []}] @ expr_path)
2520
| Pexp_ident {txt = Lident txt} -> some_if_has_cursor (txt, expr_path)
2621
| Pexp_construct ({txt = Lident "()"}, _) -> some_if_has_cursor ("", expr_path)
27-
| Pexp_construct ({txt = Lident txt}, None) ->
22+
| Pexp_construct ({txt = Lident txt}, {txt = []}) ->
2823
some_if_has_cursor (txt, expr_path)
29-
| Pexp_variant (label, None) -> some_if_has_cursor ("#" ^ label, expr_path)
24+
| Pexp_variant (label, {txt = []}) ->
25+
some_if_has_cursor ("#" ^ label, expr_path)
3026
| Pexp_array array_patterns -> (
3127
let next_expr_path = [Completable.NArray] @ expr_path in
3228
(* No fields but still has cursor = empty completion *)
@@ -122,98 +118,82 @@ let rec traverse_expr (exp : Parsetree.expression) ~expr_path ~pos
122118
| _ -> None))
123119
| Pexp_construct
124120
( {txt},
125-
Some {pexp_loc; pexp_desc = Pexp_construct ({txt = Lident "()"}, _)} )
121+
{
122+
txt = [{pexp_loc; pexp_desc = Pexp_construct ({txt = Lident "()"}, _)}];
123+
} )
126124
when loc_has_cursor pexp_loc ->
127125
(* Empty payload with cursor, like: Test(<com>) *)
128126
Some
129127
( "",
130128
[
131129
Completable.NVariantPayload
132-
{constructor_name = Utils.get_unqualified_name txt; item_num = 0};
133-
]
134-
@ expr_path )
135-
| Pexp_construct ({txt}, Some e)
136-
when pos >= (e.pexp_loc |> Loc.end_)
137-
&& first_char_before_cursor_no_white = Some ','
138-
&& is_expr_tuple e = false ->
139-
(* Empty payload with trailing ',', like: Test(true, <com>) *)
140-
Some
141-
( "",
142-
[
143-
Completable.NVariantPayload
144-
{constructor_name = Utils.get_unqualified_name txt; item_num = 1};
130+
{
131+
constructor_name = Longident.last txt;
132+
item_num = 0;
133+
source_arity = 1;
134+
};
145135
]
146136
@ expr_path )
147-
| Pexp_construct ({txt}, Some {pexp_loc; pexp_desc = Pexp_tuple tuple_items})
148-
when loc_has_cursor pexp_loc ->
149-
tuple_items
137+
| Pexp_construct ({txt}, {txt = args}) when loc_has_cursor exp.pexp_loc ->
138+
args
150139
|> traverse_expr_tuple_items ~first_char_before_cursor_no_white ~pos
151140
~next_expr_path:(fun item_num ->
152141
[
153142
Completable.NVariantPayload
154-
{constructor_name = Utils.get_unqualified_name txt; item_num};
143+
{
144+
constructor_name = Longident.last txt;
145+
item_num;
146+
source_arity = List.length args;
147+
};
155148
]
156149
@ expr_path)
157150
~result_from_found_item_num:(fun item_num ->
158151
[
159152
Completable.NVariantPayload
160153
{
161-
constructor_name = Utils.get_unqualified_name txt;
154+
constructor_name = Longident.last txt;
162155
item_num = item_num + 1;
156+
source_arity = List.length args;
163157
};
164158
]
165159
@ expr_path)
166-
| Pexp_construct ({txt}, Some p) when loc_has_cursor exp.pexp_loc ->
167-
p
168-
|> traverse_expr ~first_char_before_cursor_no_white ~pos
169-
~expr_path:
170-
([
171-
Completable.NVariantPayload
172-
{
173-
constructor_name = Utils.get_unqualified_name txt;
174-
item_num = 0;
175-
};
176-
]
177-
@ expr_path)
178160
| Pexp_variant
179-
(txt, Some {pexp_loc; pexp_desc = Pexp_construct ({txt = Lident "()"}, _)})
161+
( txt,
162+
{
163+
txt = [{pexp_loc; pexp_desc = Pexp_construct ({txt = Lident "()"}, _)}];
164+
} )
180165
when loc_has_cursor pexp_loc ->
181166
(* Empty payload with cursor, like: #test(<com>) *)
182167
Some
183168
( "",
184-
[Completable.NPolyvariantPayload {constructor_name = txt; item_num = 0}]
185-
@ expr_path )
186-
| Pexp_variant (txt, Some e)
187-
when pos >= (e.pexp_loc |> Loc.end_)
188-
&& first_char_before_cursor_no_white = Some ','
189-
&& is_expr_tuple e = false ->
190-
(* Empty payload with trailing ',', like: #test(true, <com>) *)
191-
Some
192-
( "",
193-
[Completable.NPolyvariantPayload {constructor_name = txt; item_num = 1}]
169+
[
170+
Completable.NPolyvariantPayload
171+
{constructor_name = txt; item_num = 0; source_arity = 1};
172+
]
194173
@ expr_path )
195-
| Pexp_variant (txt, Some {pexp_loc; pexp_desc = Pexp_tuple tuple_items})
196-
when loc_has_cursor pexp_loc ->
197-
tuple_items
174+
| Pexp_variant (txt, {txt = args}) when loc_has_cursor exp.pexp_loc ->
175+
args
198176
|> traverse_expr_tuple_items ~first_char_before_cursor_no_white ~pos
199177
~next_expr_path:(fun item_num ->
200-
[Completable.NPolyvariantPayload {constructor_name = txt; item_num}]
178+
[
179+
Completable.NPolyvariantPayload
180+
{
181+
constructor_name = txt;
182+
item_num;
183+
source_arity = List.length args;
184+
};
185+
]
201186
@ expr_path)
202187
~result_from_found_item_num:(fun item_num ->
203188
[
204189
Completable.NPolyvariantPayload
205-
{constructor_name = txt; item_num = item_num + 1};
190+
{
191+
constructor_name = txt;
192+
item_num = item_num + 1;
193+
source_arity = List.length args;
194+
};
206195
]
207196
@ expr_path)
208-
| Pexp_variant (txt, Some p) when loc_has_cursor exp.pexp_loc ->
209-
p
210-
|> traverse_expr ~first_char_before_cursor_no_white ~pos
211-
~expr_path:
212-
([
213-
Completable.NPolyvariantPayload
214-
{constructor_name = txt; item_num = 0};
215-
]
216-
@ expr_path)
217197
| _ -> None
218198

219199
and traverse_expr_tuple_items tuple_items ~next_expr_path
@@ -288,28 +268,7 @@ let complete_constructor_payload ~pos_before_cursor
288268
with
289269
| None -> None
290270
| Some (prefix, nested) ->
291-
(* The nested path must start with the constructor name found, plus
292-
the target argument number for the constructor. We translate to
293-
that here, because we need to account for multi arg constructors
294-
being represented as tuples. *)
295-
let nested =
296-
match List.rev nested with
297-
| Completable.NTupleItem {item_num} :: rest ->
298-
[
299-
Completable.NVariantPayload
300-
{constructor_name = Longident.last constructor_lid.txt; item_num};
301-
]
302-
@ rest
303-
| nested ->
304-
[
305-
Completable.NVariantPayload
306-
{
307-
constructor_name = Longident.last constructor_lid.txt;
308-
item_num = 0;
309-
};
310-
]
311-
@ nested
312-
in
271+
let nested = List.rev nested in
313272
let variant_ctx_path =
314273
Completable.CTypeAtPos
315274
{constructor_lid.loc with loc_start = constructor_lid.loc.loc_end}

0 commit comments

Comments
 (0)