Skip to content

Commit 4c22226

Browse files
committed
Compiler: support for es6 import/export
1 parent 8d87bba commit 4c22226

15 files changed

+813
-22
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Compiler: change control-flow compilation strategy (#1496)
66
* Compiler: Dead code elimination of unused references (#2076)
77
* Compiler: reduce memory consumption (#1516)
8+
* Compiler: support for es6 import and export construct
89
* Lib: add download attribute to anchor element
910
* Misc: switch CI to OCaml 5.1
1011
* Misc: preliminary support for OCaml 5.2

compiler/bin-jsoo_minify/jsoo_minify.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ let f { Cmd_arg.common; output_file; use_stdin; files } =
8181
let true_ () = true in
8282
let open Config in
8383
let passes : ((unit -> bool) * (unit -> Js_traverse.mapper)) list =
84-
[ (Flag.shortvar, fun () -> (new Js_traverse.rename_variable :> Js_traverse.mapper))
84+
[ ( Flag.shortvar
85+
, fun () -> (new Js_traverse.rename_variable ~esm:false :> Js_traverse.mapper) )
8586
; (true_, fun () -> new Js_traverse.simpl)
8687
; (true_, fun () -> new Js_traverse.clean)
8788
]

compiler/lib/driver.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ if (typeof module === 'object' && module.exports) {
575575
if Config.Flag.shortvar ()
576576
then (
577577
let t5 = Timer.make () in
578-
let js = (new Js_traverse.rename_variable)#program js in
578+
let js = (new Js_traverse.rename_variable ~esm:false)#program js in
579579
if times () then Format.eprintf " shortten vars: %a@." Timer.print t5;
580580
js)
581581
else js

compiler/lib/javascript.ml

+40
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ and statement =
346346
| Throw_statement of expression
347347
| Try_statement of block * (formal_parameter option * block) option * block option
348348
| Debugger_statement
349+
| Import of import * Parse_info.t
350+
| Export of export * Parse_info.t
349351

350352
and ('left, 'right) either =
351353
| Left of 'left
@@ -422,6 +424,44 @@ and function_body = statement_list
422424

423425
and program = statement_list
424426

427+
and export =
428+
| ExportVar of variable_declaration_kind * variable_declaration list
429+
| ExportFun of ident * function_declaration
430+
| ExportClass of ident * class_declaration
431+
| ExportNames of (ident * Utf8_string.t) list
432+
(* default *)
433+
| ExportDefaultFun of ident * function_declaration
434+
| ExportDefaultClass of ident * class_declaration
435+
| ExportDefaultExpression of expression
436+
(* from *)
437+
| ExportFrom of
438+
{ kind : export_from_kind
439+
; from : Utf8_string.t
440+
}
441+
| CoverExportFrom of early_error
442+
443+
and export_from_kind =
444+
| Export_all of Utf8_string.t option
445+
| Export_names of (Utf8_string.t * Utf8_string.t) list
446+
447+
and import =
448+
{ from : Utf8_string.t
449+
; kind : import_kind
450+
}
451+
452+
and import_default = ident
453+
454+
and import_kind =
455+
| Namespace of import_default option * ident
456+
(* import * as name from "fname" *)
457+
(* import defaultname, * as name from "fname" *)
458+
| Named of import_default option * (Utf8_string.t * ident) list
459+
(* import { 'a' as a, ...} from "fname" *)
460+
(* import defaultname, { 'a' as a, ...} from "fname" *)
461+
| Default of import_default
462+
(* import defaultname from "fname" *)
463+
| SideEffect (* import "fname" *)
464+
425465
and program_with_annots = (statement_list * (Js_token.Annot.t * Parse_info.t) list) list
426466

427467
let compare_ident t1 t2 =

compiler/lib/javascript.mli

+40
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ and statement =
266266
| Throw_statement of expression
267267
| Try_statement of block * (formal_parameter option * block) option * block option
268268
| Debugger_statement
269+
| Import of import * Parse_info.t
270+
| Export of export * Parse_info.t
269271

270272
and ('left, 'right) either =
271273
| Left of 'left
@@ -342,6 +344,44 @@ and function_body = statement_list
342344

343345
and program = statement_list
344346

347+
and export =
348+
| ExportVar of variable_declaration_kind * variable_declaration list
349+
| ExportFun of ident * function_declaration
350+
| ExportClass of ident * class_declaration
351+
| ExportNames of (ident * Utf8_string.t) list
352+
(* default *)
353+
| ExportDefaultFun of ident * function_declaration
354+
| ExportDefaultClass of ident * class_declaration
355+
| ExportDefaultExpression of expression
356+
(* from *)
357+
| ExportFrom of
358+
{ kind : export_from_kind
359+
; from : Utf8_string.t
360+
}
361+
| CoverExportFrom of early_error
362+
363+
and export_from_kind =
364+
| Export_all of Utf8_string.t option
365+
| Export_names of (Utf8_string.t * Utf8_string.t) list
366+
367+
and import =
368+
{ from : Utf8_string.t
369+
; kind : import_kind
370+
}
371+
372+
and import_default = ident
373+
374+
and import_kind =
375+
| Namespace of import_default option * ident
376+
(* import * as name from "fname" *)
377+
(* import defaultname, * as name from "fname" *)
378+
| Named of import_default option * (Utf8_string.t * ident) list
379+
(* import { 'a' as a, ...} from "fname" *)
380+
(* import defaultname, { 'a' as a, ...} from "fname" *)
381+
| Default of import_default
382+
(* import defaultname from "fname" *)
383+
| SideEffect (* import "fname" *)
384+
345385
and program_with_annots = (statement_list * (Js_token.Annot.t * Parse_info.t) list) list
346386

347387
val compare_ident : ident -> ident -> int

compiler/lib/js_output.ml

+146-7
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ struct
289289
| Try_statement _
290290
| Function_declaration _
291291
| Class_declaration _
292-
| Debugger_statement -> false
292+
| Debugger_statement
293+
| Import _
294+
| Export _ -> false
293295

294296
let starts_with ~obj ~funct ~let_identifier ~async_identifier l e =
295297
let rec traverse l e =
@@ -368,6 +370,13 @@ struct
368370
Buffer.add_char b quote;
369371
PP.string f (Buffer.contents b)
370372

373+
let pp_string_lit f (Stdlib.Utf8_string.Utf8 s) =
374+
let quote = best_string_quote s in
375+
pp_string f ~quote s
376+
377+
let pp_ident_or_string_lit f (Stdlib.Utf8_string.Utf8 s_lit as s) =
378+
if is_ident s_lit then PP.string f s_lit else pp_string_lit f s
379+
371380
let rec comma_list f f_elt l =
372381
match l with
373382
| [] -> ()
@@ -523,9 +532,7 @@ struct
523532
then (
524533
PP.string f ")";
525534
PP.end_group f)
526-
| EStr (Utf8 s) ->
527-
let quote = best_string_quote s in
528-
pp_string f ~quote s
535+
| EStr x -> pp_string_lit f x
529536
| ETemplate l -> template f l
530537
| EBool b -> PP.string f (if b then "true" else "false")
531538
| ENum num ->
@@ -833,9 +840,7 @@ struct
833840
and property_name f n =
834841
match n with
835842
| PNI (Utf8 s) -> PP.string f s
836-
| PNS (Utf8 s) ->
837-
let quote = best_string_quote s in
838-
pp_string f ~quote s
843+
| PNS s -> pp_string_lit f s
839844
| PNN v -> expression Expression f (ENum v)
840845
| PComputed e ->
841846
PP.string f "[";
@@ -1409,6 +1414,140 @@ struct
14091414
PP.string f "finally";
14101415
block f b);
14111416
PP.end_group f
1417+
| Import ({ kind; from }, _loc) ->
1418+
PP.start_group f 0;
1419+
PP.string f "import";
1420+
(match kind with
1421+
| SideEffect -> ()
1422+
| Default i ->
1423+
PP.space f;
1424+
ident f i
1425+
| Namespace (def, i) ->
1426+
Option.iter def ~f:(fun def ->
1427+
PP.space f;
1428+
ident f def;
1429+
PP.string f ",");
1430+
PP.space f;
1431+
PP.string f "* as ";
1432+
ident f i
1433+
| Named (def, l) ->
1434+
Option.iter def ~f:(fun def ->
1435+
PP.space f;
1436+
ident f def;
1437+
PP.string f ",");
1438+
PP.space f;
1439+
PP.string f "{";
1440+
PP.space f;
1441+
comma_list
1442+
f
1443+
(fun f (s, i) ->
1444+
if match i with
1445+
| S { name; _ } when Stdlib.Utf8_string.equal name s -> true
1446+
| _ -> false
1447+
then ident f i
1448+
else (
1449+
pp_ident_or_string_lit f s;
1450+
PP.string f " as ";
1451+
ident f i))
1452+
l;
1453+
PP.space f;
1454+
PP.string f "}");
1455+
(match kind with
1456+
| SideEffect -> ()
1457+
| _ ->
1458+
PP.space f;
1459+
PP.string f "from");
1460+
PP.space f;
1461+
pp_string_lit f from;
1462+
PP.string f ";";
1463+
PP.end_group f
1464+
| Export (e, _loc) ->
1465+
PP.start_group f 0;
1466+
PP.string f "export";
1467+
(match e with
1468+
| ExportNames l ->
1469+
PP.space f;
1470+
PP.string f "{";
1471+
PP.space f;
1472+
comma_list
1473+
f
1474+
(fun f (i, s) ->
1475+
if match i with
1476+
| S { name; _ } when Stdlib.Utf8_string.equal name s -> true
1477+
| _ -> false
1478+
then ident f i
1479+
else (
1480+
ident f i;
1481+
PP.string f " as ";
1482+
pp_ident_or_string_lit f s))
1483+
l;
1484+
PP.space f;
1485+
PP.string f "};"
1486+
| ExportFrom { kind; from } ->
1487+
PP.space f;
1488+
(match kind with
1489+
| Export_all None -> PP.string f "*"
1490+
| Export_all (Some s) ->
1491+
PP.string f "* as ";
1492+
pp_ident_or_string_lit f s
1493+
| Export_names l ->
1494+
PP.string f "{";
1495+
PP.space f;
1496+
comma_list
1497+
f
1498+
(fun f (a, b) ->
1499+
if Stdlib.Utf8_string.equal a b
1500+
then pp_ident_or_string_lit f a
1501+
else (
1502+
pp_ident_or_string_lit f a;
1503+
PP.string f " as ";
1504+
pp_ident_or_string_lit f b))
1505+
l;
1506+
PP.space f;
1507+
PP.string f "}");
1508+
PP.space f;
1509+
PP.string f "from";
1510+
PP.space f;
1511+
pp_string_lit f from;
1512+
PP.string f ";"
1513+
| ExportDefaultExpression ((EFun _ | EClass _) as e) ->
1514+
PP.space f;
1515+
PP.string f "default";
1516+
PP.space f;
1517+
expression Expression f e
1518+
| ExportDefaultExpression e ->
1519+
PP.space f;
1520+
PP.string f "default";
1521+
PP.space f;
1522+
parenthesized_expression
1523+
~last_semi
1524+
~obj:true
1525+
~funct:true
1526+
~let_identifier:true
1527+
Expression
1528+
f
1529+
e
1530+
| ExportDefaultFun (id, decl) ->
1531+
PP.space f;
1532+
PP.string f "default";
1533+
PP.space f;
1534+
statement f (Function_declaration (id, decl), loc)
1535+
| ExportDefaultClass (id, decl) ->
1536+
PP.space f;
1537+
PP.string f "default";
1538+
PP.space f;
1539+
statement f (Class_declaration (id, decl), loc)
1540+
| ExportFun (id, decl) ->
1541+
PP.space f;
1542+
statement f (Function_declaration (id, decl), loc)
1543+
| ExportClass (id, decl) ->
1544+
PP.space f;
1545+
statement f (Class_declaration (id, decl), loc)
1546+
| ExportVar (k, l) ->
1547+
PP.space f;
1548+
variable_declaration_list k (not can_omit_semi) f l
1549+
| CoverExportFrom e -> early_error e);
1550+
PP.end_group f
14121551
14131552
and statement_list f ?skip_last_semi b =
14141553
match b with

0 commit comments

Comments
 (0)