Skip to content

Commit db7eee6

Browse files
committed
Intial exploration of JSX ast
Map child expressions Initial mapping of Pexp_jsx_fragment to 0 Correct location in mapping Update analysis for jsx_fragment Remove unused code Print something for ml print Commit invalid test results for reference Try improve printing Correct fragment range, try and print comments Indent jsx Process comments from children inside fragment Attach comments to fragment tags Fix comment Improve comment formatting Print single element on same line Update comment WIP: Debug More debugging Works Fix some jsx printing Fix the test Clean up Update tests with location changes
1 parent 26a15aa commit db7eee6

29 files changed

+266
-198
lines changed

analysis/src/CompletionFrontEnd.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,8 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
12321232
then ValueOrField
12331233
else Value);
12341234
}))
1235-
| Pexp_construct ({txt = Lident ("::" | "()")}, _) ->
1235+
| Pexp_construct ({txt = Lident ("::" | "()")}, _) | Pexp_jsx_fragment _
1236+
->
12361237
(* Ignore list expressions, used in JSX, unit, and more *) ()
12371238
| Pexp_construct (lid, eOpt) -> (
12381239
let lidPath = flattenLidCheckDot lid in

analysis/src/Utils.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ let identifyPexp pexp =
111111
| Pexp_pack _ -> "Pexp_pack"
112112
| Pexp_extension _ -> "Pexp_extension"
113113
| Pexp_open _ -> "Pexp_open"
114+
| Pexp_jsx_fragment _ -> "Pexp_jsx_fragment"
114115

115116
let identifyPpat pat =
116117
match pat with
@@ -154,6 +155,10 @@ let isJsxComponent (vb : Parsetree.value_binding) =
154155
|> List.exists (function
155156
| {Location.txt = "react.component" | "jsx.component"}, _payload -> true
156157
| _ -> false)
158+
||
159+
match vb.pvb_expr.pexp_desc with
160+
| Parsetree.Pexp_jsx_fragment _ -> true
161+
| _ -> false
157162

158163
let checkName name ~prefix ~exact =
159164
if exact then name = prefix else startsWith name prefix

compiler/frontend/bs_ast_mapper.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ module E = struct
366366
| Pexp_open (ovf, lid, e) ->
367367
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
368368
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
369+
| Pexp_jsx_fragment (o, xs, c) ->
370+
jsx_fragment o (List.map (sub.expr sub) xs) c
369371
end
370372

371373
module P = struct

compiler/ml/ast_helper.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,35 @@ module Exp = struct
180180
let pack ?loc ?attrs a = mk ?loc ?attrs (Pexp_pack a)
181181
let open_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_open (a, b, c))
182182
let extension ?loc ?attrs a = mk ?loc ?attrs (Pexp_extension a)
183+
let jsx_fragment ?loc ?attrs a b c =
184+
mk ?loc ?attrs (Pexp_jsx_fragment (a, b, c))
183185

184186
let case lhs ?guard rhs = {pc_lhs = lhs; pc_guard = guard; pc_rhs = rhs}
187+
188+
let make_list_expression loc seq ext_opt =
189+
let rec handle_seq = function
190+
| [] -> (
191+
match ext_opt with
192+
| Some ext -> ext
193+
| None ->
194+
let loc = {loc with Location.loc_ghost = true} in
195+
let nil = Location.mkloc (Longident.Lident "[]") loc in
196+
construct ~loc nil None)
197+
| e1 :: el ->
198+
let exp_el = handle_seq el in
199+
let loc =
200+
Location.
201+
{
202+
loc_start = e1.Parsetree.pexp_loc.Location.loc_start;
203+
loc_end = exp_el.pexp_loc.loc_end;
204+
loc_ghost = false;
205+
}
206+
in
207+
let arg = tuple ~loc [e1; exp_el] in
208+
construct ~loc (Location.mkloc (Longident.Lident "::") loc) (Some arg)
209+
in
210+
let expr = handle_seq seq in
211+
{expr with pexp_loc = loc}
185212
end
186213

187214
module Mty = struct

compiler/ml/ast_helper.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,18 @@ module Exp : sig
208208
val open_ :
209209
?loc:loc -> ?attrs:attrs -> override_flag -> lid -> expression -> expression
210210
val extension : ?loc:loc -> ?attrs:attrs -> extension -> expression
211+
val jsx_fragment :
212+
?loc:loc ->
213+
?attrs:attrs ->
214+
Lexing.position ->
215+
expression list ->
216+
Lexing.position ->
217+
expression
211218

212219
val case : pattern -> ?guard:expression -> expression -> case
220+
221+
val make_list_expression :
222+
Location.t -> expression list -> expression option -> expression
213223
end
214224

215225
(** Value declarations *)

compiler/ml/ast_iterator.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ module E = struct
344344
iter_loc sub lid;
345345
sub.expr sub e
346346
| Pexp_extension x -> sub.extension sub x
347+
| Pexp_jsx_fragment (_, xs, _) -> List.iter (sub.expr sub) xs
347348
end
348349

349350
module P = struct

compiler/ml/ast_mapper.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ module E = struct
329329
| Pexp_open (ovf, lid, e) ->
330330
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
331331
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
332+
| Pexp_jsx_fragment (o, xs, c) ->
333+
jsx_fragment ~loc ~attrs o (List.map (sub.expr sub) xs) c
332334
end
333335

334336
module P = struct

compiler/ml/ast_mapper_to0.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,18 @@ module E = struct
407407
| Pexp_open (ovf, lid, e) ->
408408
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
409409
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
410+
| Pexp_jsx_fragment (o, xs, c) ->
411+
(*
412+
The location of Pexp_jsx_fragment is from the start of < till the end of />.
413+
This is not the case in the old AST. There it is from >...</
414+
*)
415+
let loc = {loc with loc_start = o; loc_end = c} in
416+
let list_expr = Ast_helper.Exp.make_list_expression loc xs None in
417+
let mapped = sub.expr sub list_expr in
418+
let jsx_attr =
419+
sub.attribute sub (Location.mknoloc "JSX", Parsetree.PStr [])
420+
in
421+
{mapped with pexp_attributes = jsx_attr :: attrs}
410422
end
411423

412424
module P = struct

compiler/ml/depend.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ let rec add_expr bv exp =
289289
| Pstr_eval ({pexp_desc = Pexp_construct (c, None)}, _) -> add bv c
290290
| _ -> handle_extension e)
291291
| Pexp_extension e -> handle_extension e
292+
| Pexp_jsx_fragment (_, xs, _) -> List.iter (add_expr bv) xs
292293

293294
and add_cases bv cases = List.iter (add_case bv) cases
294295

compiler/ml/parsetree.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,14 @@ and expression_desc =
313313
let open M in E
314314
let! open M in E *)
315315
| Pexp_extension of extension
316-
(* [%id] *)
317-
(* . *)
316+
(* [%id] *)
317+
(* . *)
318+
(* represents <> foo </> , the entire range is stored in the expression , we keep track of >, children and </ *)
319+
| Pexp_jsx_fragment of
320+
(* > *) Lexing.position
321+
* (* children *)
322+
expression list
323+
* (* </ *) Lexing.position
318324

319325
and case = {
320326
(* (P -> E) or (P when E0 -> E) *)

0 commit comments

Comments
 (0)