Skip to content

Commit

Permalink
Compiler: import at toplevel only
Browse files Browse the repository at this point in the history
  • Loading branch information
hhugo committed Nov 16, 2023
1 parent fd49ad9 commit 9b46121
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 23 deletions.
4 changes: 2 additions & 2 deletions compiler/lib/javascript.ml
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ and statement =
| Throw_statement of expression
| Try_statement of block * (formal_parameter option * block) option * block option
| Debugger_statement
| Import of import
| Export of export
| Import of import * Parse_info.t
| Export of export * Parse_info.t

and ('left, 'right) either =
| Left of 'left
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/javascript.mli
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,8 @@ and statement =
| Throw_statement of expression
| Try_statement of block * (formal_parameter option * block) option * block option
| Debugger_statement
| Import of import
| Export of export
| Import of import * Parse_info.t
| Export of export * Parse_info.t

and ('left, 'right) either =
| Left of 'left
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/js_output.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,7 @@ struct
PP.string f "finally";
block f b);
PP.end_group f
| Import { kind; from } ->
| Import ({ kind; from }, _loc) ->
PP.start_group f 0;
PP.string f "import";
(match kind with
Expand Down Expand Up @@ -1461,7 +1461,7 @@ struct
pp_string_lit f from;
PP.string f ";";
PP.end_group f
| Export e ->
| Export (e, _loc) ->
PP.start_group f 0;
PP.string f "export";
(match e with
Expand Down
27 changes: 18 additions & 9 deletions compiler/lib/js_parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,11 @@ decl:

import_decl:
| T_IMPORT kind=import_clause from=from_clause sc
{ Import { from; kind }, p $symbolstartpos }
{ let pos = $symbolstartpos in
Import ({ from; kind }, pi pos), p pos }
| T_IMPORT from=module_specifier sc
{ Import { from; kind = SideEffect }, p $symbolstartpos }
{ let pos = $symbolstartpos in
Import ({ from; kind = SideEffect }, pi pos), p pos }

import_clause:
| import_default { Default $1 }
Expand Down Expand Up @@ -343,22 +345,25 @@ export_decl:
with Invalid pos ->
CoverExportFrom (early_error (pi pos))
in
Export k, p $symbolstartpos }
let pos = $symbolstartpos in
Export (k, pi pos), p pos }
| T_EXPORT v=variable_stmt sc
{
let pos = $symbolstartpos in
let k = match v with
| Variable_statement (k,l) -> ExportVar (k, l)
| _ -> assert false
in
Export k, p $symbolstartpos }
Export (k, pi pos), p pos }
| T_EXPORT d=decl sc
{ let k = match d with
| Variable_statement (k,l),_ -> ExportVar (k,l)
| Function_declaration (id, decl),_ -> ExportFun (id,decl)
| Class_declaration (id, decl),_ -> ExportClass (id,decl)
| _ -> assert false
in
Export k, p $symbolstartpos }
let pos = $symbolstartpos in
Export (k,pi pos), p pos }
(* in theory just func/gen/class, no lexical_decl *)
| T_EXPORT T_DEFAULT e=assignment_expr sc
{
Expand All @@ -369,20 +374,24 @@ export_decl:
ExportDefaultClass (id, decl)
| e -> ExportDefaultExpression e
in
Export k, p $symbolstartpos }
let pos = $symbolstartpos in
Export (k,pi pos), p pos }
| T_EXPORT "*" T_FROM from=module_specifier sc {
let kind = Export_all None in
Export (ExportFrom {from; kind}), p $symbolstartpos
let pos = $symbolstartpos in
Export (ExportFrom ({from; kind}),pi pos), p pos
}
| T_EXPORT "*" T_AS id=string_or_ident T_FROM from=module_specifier sc {
let (_,id,_) = id in
let kind = Export_all (Some id) in
Export (ExportFrom {from; kind}), p $symbolstartpos
let pos = $symbolstartpos in
Export (ExportFrom ({from; kind}), pi pos), p pos
}
| T_EXPORT names=export_clause T_FROM from=module_specifier sc {
let names = List.map (fun ((_,a,_), (_,b,_)) -> a, b) names in
let kind = Export_names names in
Export (ExportFrom {from; kind}), p $symbolstartpos
let pos = $symbolstartpos in
Export (ExportFrom ({from; kind}), pi pos), p pos
}

export_specifier:
Expand Down
12 changes: 6 additions & 6 deletions compiler/lib/js_traverse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ class map : mapper =
, match final with
| None -> None
| Some s -> Some (m#block s) )
| Import import -> Import (m#import import)
| Export export -> Export (m#export export)
| Import (import, loc) -> Import (m#import import, loc)
| Export (export, loc) -> Export (m#export export, loc)

method import { from; kind } =
let kind =
Expand Down Expand Up @@ -515,8 +515,8 @@ class iter : iterator =
match final with
| None -> ()
| Some s -> m#block s)
| Import x -> m#import x
| Export x -> m#export x
| Import (x, _loc) -> m#import x
| Export (x, _loc) -> m#export x

method import { from = _; kind } =
match kind with
Expand Down Expand Up @@ -1060,7 +1060,7 @@ class free =
| Some f -> Some (m#block f)
in
Try_statement (b, w, f)
| Import { from = _; kind } ->
| Import ({ from = _; kind }, _) ->
(match kind with
| Namespace (iopt, i) ->
Option.iter ~f:m#def_local iopt;
Expand Down Expand Up @@ -1142,7 +1142,7 @@ class rename_variable =
List.iter l ~f:(fun (_, s) -> m#statements s);
Option.iter def ~f:(fun l -> m#statements l);
List.iter l' ~f:(fun (_, s) -> m#statements s)
| _, Import { kind; from = _ } -> (
| _, Import ({ kind; from = _ }, _loc) -> (
match kind with
| Namespace (iopt, i) ->
Option.iter ~f:decl_var iopt;
Expand Down
20 changes: 18 additions & 2 deletions compiler/lib/parse_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,26 @@ let parse_aux the_parser (lexbuf : Lexer.t) =
raise (Parsing_error (Parse_info.t_of_pos p))

let fail_early =
object
inherit Js_traverse.iter
object (m)
inherit Js_traverse.iter as super

method early_error p = raise (Parsing_error p.loc)

method statement s =
match s with
| Import (_, loc) -> raise (Parsing_error loc)
| Export (_, loc) -> raise (Parsing_error loc)
| _ -> super#statement s

method program p =
List.iter p ~f:(fun ((p : Javascript.statement), _loc) ->
match p with
| Import _ -> super#statement p
| Export (e, _) -> (
match e with
| CoverExportFrom e -> m#early_error e
| _ -> super#statement p)
| _ -> super#statement p)
end

let check_program p = List.iter p ~f:(function _, p -> fail_early#program [ p ])
Expand Down

0 comments on commit 9b46121

Please sign in to comment.