Skip to content

Commit 990722a

Browse files
gkzmeta-codesync[bot]
authored andcommitted
[flow][tslib] Support export = ... and import foo = ...
Summary: This adds support for two [TypeScript-style](https://www.typescriptlang.org/docs/handbook/modules/reference.html#export--and-import--require) syntactic forms behind the `tslib_syntax` flag: 1. `export = <expression>` (ExportAssignment) — the equivalent of `module.exports = ...` 2. `import <id> = require("<module>")` and `import <id> = <QualifiedName>` (ImportEqualsDeclaration) — the equivalent of `const <id> = require(...)` Changelog: [internal] Reviewed By: SamChou19815 Differential Revision: D92915376 fbshipit-source-id: 70f67a14dce1abbce6d2978a3507c83f3aa53f60
1 parent 3b332a3 commit 990722a

Some content is hidden

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

43 files changed

+1055
-14
lines changed

src/analysis/env_builder/name_def.ml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,6 +2646,34 @@ class def_finder ~autocomplete_hooks ~react_jsx env_info toplevel_scope =
26462646
default;
26472647
super#import_declaration loc decl
26482648

2649+
method! import_equals_declaration _loc decl =
2650+
let open Ast.Statement.ImportEqualsDeclaration in
2651+
let {
2652+
id = (id_loc, { Ast.Identifier.name = local_name; _ });
2653+
module_reference;
2654+
import_kind;
2655+
is_export = _;
2656+
comments = _;
2657+
} =
2658+
decl
2659+
in
2660+
(match module_reference with
2661+
| ExternalModuleReference (source_loc, { Ast.StringLiteral.value = source; _ }) ->
2662+
let import_reason =
2663+
mk_reason
2664+
(RDefaultImportedType (local_name, Flow_import_specifier.userland source))
2665+
id_loc
2666+
in
2667+
this#add_ordinary_binding
2668+
id_loc
2669+
import_reason
2670+
(Import { import_kind; source; source_loc; import = Default local_name })
2671+
| Identifier _ ->
2672+
(* import Foo = A.B.C: qualified name access is not resolved through
2673+
name_def/env_resolution. The binding is handled by the type_sig layer. *)
2674+
());
2675+
decl
2676+
26492677
method! call loc _ = fail loc "Should be visited by visit_call_expression"
26502678

26512679
method private visit_call_expression ~hints ~cond ~visit_callee loc expr =

src/analysis/hoister.ml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class ['loc] lexical_hoister ~(enable_enums : bool) =
7979
| (_, ExportNamedDeclaration _)
8080
| (_, ExportDefaultDeclaration _)
8181
| (_, ImportDeclaration _)
82+
| (_, ImportEqualsDeclaration _)
8283
| (_, Labeled _) ->
8384
super#statement stmt
8485
| (_, FunctionDeclaration _)
@@ -98,6 +99,7 @@ class ['loc] lexical_hoister ~(enable_enums : bool) =
9899
| (_, DeclareOpaqueType _)
99100
| (_, DoWhile _)
100101
| (_, Empty _)
102+
| (_, ExportAssignment _)
101103
| (_, Expression _)
102104
| (_, For _)
103105
| (_, ForIn _)
@@ -378,6 +380,21 @@ class ['loc] hoister ~(enable_enums : bool) ~(with_types : bool) =
378380
decl
379381
| _ -> super#import_declaration loc decl
380382

383+
method! import_equals_declaration _loc decl =
384+
let open Ast.Statement.ImportEqualsDeclaration in
385+
let { id; import_kind; _ } = decl in
386+
let open Ast.Statement.ImportDeclaration in
387+
begin
388+
match import_kind with
389+
| ImportValue -> this#add_const_binding ~kind:Bindings.Import id
390+
| ImportType
391+
| ImportTypeof
392+
when with_types ->
393+
this#add_type_binding ~imported:true id
394+
| _ -> ()
395+
end;
396+
decl
397+
381398
method! import_named_specifier
382399
~import_kind (specifier : ('loc, 'loc) Ast.Statement.ImportDeclaration.named_specifier) =
383400
let open Ast.Statement.ImportDeclaration in

src/parser/comment_attachment.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ let statement_add_comments
568568
{ s with ExportDefaultDeclaration.comments = merge_comments comments }
569569
| ExportNamedDeclaration ({ ExportNamedDeclaration.comments; _ } as s) ->
570570
ExportNamedDeclaration { s with ExportNamedDeclaration.comments = merge_comments comments }
571+
| ExportAssignment ({ ExportAssignment.comments; _ } as s) ->
572+
ExportAssignment { s with ExportAssignment.comments = merge_comments comments }
571573
| Expression ({ Expression.comments; _ } as s) ->
572574
Expression { s with Expression.comments = merge_comments comments }
573575
| For ({ For.comments; _ } as s) -> For { s with For.comments = merge_comments comments }
@@ -580,6 +582,8 @@ let statement_add_comments
580582
| If ({ If.comments; _ } as s) -> If { s with If.comments = merge_comments comments }
581583
| ImportDeclaration ({ ImportDeclaration.comments; _ } as s) ->
582584
ImportDeclaration { s with ImportDeclaration.comments = merge_comments comments }
585+
| ImportEqualsDeclaration ({ ImportEqualsDeclaration.comments; _ } as s) ->
586+
ImportEqualsDeclaration { s with ImportEqualsDeclaration.comments = merge_comments comments }
583587
| InterfaceDeclaration ({ Interface.comments; _ } as s) ->
584588
InterfaceDeclaration { s with Interface.comments = merge_comments comments }
585589
| Labeled ({ Labeled.comments; _ } as s) ->

src/parser/estree_translator.ml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ with type t = Impl.t = struct
432432
("declaration", declaration);
433433
("exportKind", string (string_of_export_kind Statement.ExportValue));
434434
]
435+
| (loc, ExportAssignment { ExportAssignment.expression = expr; comments }) ->
436+
node ?comments "ExportAssignment" loc [("expression", expression expr)]
435437
| ( loc,
436438
ImportDeclaration
437439
{ ImportDeclaration.specifiers; default; import_kind; source; attributes; comments }
@@ -473,6 +475,49 @@ with type t = Impl.t = struct
473475
]
474476
@ attributes_json
475477
)
478+
| ( loc,
479+
ImportEqualsDeclaration
480+
{
481+
ImportEqualsDeclaration.id = ident;
482+
module_reference;
483+
import_kind;
484+
is_export;
485+
comments;
486+
}
487+
) ->
488+
let module_reference_json =
489+
let open ImportEqualsDeclaration in
490+
match module_reference with
491+
| ExternalModuleReference (annot_loc, lit) ->
492+
node
493+
"ExternalModuleReference"
494+
annot_loc
495+
[("expression", string_literal (annot_loc, lit))]
496+
| Identifier git ->
497+
let open Type.Generic.Identifier in
498+
let generic_id = function
499+
| Unqualified id -> identifier id
500+
| Qualified q -> generic_type_qualified_identifier q
501+
| ImportTypeAnnot it -> import_type it
502+
in
503+
generic_id git
504+
in
505+
let import_kind_str =
506+
match import_kind with
507+
| ImportDeclaration.ImportType -> "type"
508+
| ImportDeclaration.ImportTypeof -> "typeof"
509+
| ImportDeclaration.ImportValue -> "value"
510+
in
511+
node
512+
?comments
513+
"ImportEqualsDeclaration"
514+
loc
515+
[
516+
("id", identifier ident);
517+
("moduleReference", module_reference_json);
518+
("importKind", string import_kind_str);
519+
("isExport", bool is_export);
520+
]
476521
and expression =
477522
let open Expression in
478523
function

src/parser/flow_ast.ml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,14 @@ and Statement : sig
12361236
[@@deriving show]
12371237
end
12381238

1239+
module ExportAssignment : sig
1240+
type ('M, 'T) t = {
1241+
expression: ('M, 'T) Expression.t;
1242+
comments: ('M, unit) Syntax.t option;
1243+
}
1244+
[@@deriving show]
1245+
end
1246+
12391247
module ExportNamedDeclaration : sig
12401248
module ExportSpecifier : sig
12411249
type ('M, 'T) t = 'M * ('M, 'T) t'
@@ -1361,6 +1369,21 @@ and Statement : sig
13611369
[@@deriving show]
13621370
end
13631371

1372+
module ImportEqualsDeclaration : sig
1373+
type ('M, 'T) module_reference =
1374+
| ExternalModuleReference of ('T * 'M StringLiteral.t)
1375+
| Identifier of ('M, 'T) Type.Generic.Identifier.t
1376+
1377+
and ('M, 'T) t = {
1378+
id: ('M, 'T) Identifier.t;
1379+
module_reference: ('M, 'T) module_reference;
1380+
import_kind: ImportDeclaration.import_kind;
1381+
is_export: bool;
1382+
comments: ('M, unit) Syntax.t option;
1383+
}
1384+
[@@deriving show]
1385+
end
1386+
13641387
module Expression : sig
13651388
type ('M, 'T) t = {
13661389
expression: ('M, 'T) Expression.t;
@@ -1404,13 +1427,15 @@ and Statement : sig
14041427
| EnumDeclaration of ('M, 'T) EnumDeclaration.t
14051428
| ExportDefaultDeclaration of ('M, 'T) ExportDefaultDeclaration.t
14061429
| ExportNamedDeclaration of ('M, 'T) ExportNamedDeclaration.t
1430+
| ExportAssignment of ('M, 'T) ExportAssignment.t
14071431
| Expression of ('M, 'T) Expression.t
14081432
| For of ('M, 'T) For.t
14091433
| ForIn of ('M, 'T) ForIn.t
14101434
| ForOf of ('M, 'T) ForOf.t
14111435
| FunctionDeclaration of ('M, 'T) Function.t
14121436
| If of ('M, 'T) If.t
14131437
| ImportDeclaration of ('M, 'T) ImportDeclaration.t
1438+
| ImportEqualsDeclaration of ('M, 'T) ImportEqualsDeclaration.t
14141439
| InterfaceDeclaration of ('M, 'T) Interface.t
14151440
| Labeled of ('M, 'T) Labeled.t
14161441
| Match of ('M, 'T) match_statement

src/parser/flow_ast_mapper.ml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ class ['loc] mapper =
168168
id_loc this#export_named_declaration loc decl stmt (fun decl ->
169169
(loc, ExportNamedDeclaration decl)
170170
)
171+
| (loc, ExportAssignment assign) ->
172+
id_loc this#export_assignment loc assign stmt (fun assign -> (loc, ExportAssignment assign))
171173
| (loc, Expression expr) ->
172174
id_loc this#expression_statement loc expr stmt (fun expr -> (loc, Expression expr))
173175
| (loc, For for_stmt) ->
@@ -182,6 +184,10 @@ class ['loc] mapper =
182184
id_loc this#if_statement loc if_stmt stmt (fun if_stmt -> (loc, If if_stmt))
183185
| (loc, ImportDeclaration decl) ->
184186
id_loc this#import_declaration loc decl stmt (fun decl -> (loc, ImportDeclaration decl))
187+
| (loc, ImportEqualsDeclaration decl) ->
188+
id_loc this#import_equals_declaration loc decl stmt (fun decl ->
189+
(loc, ImportEqualsDeclaration decl)
190+
)
185191
| (loc, InterfaceDeclaration stuff) ->
186192
id_loc this#interface_declaration loc stuff stmt (fun stuff ->
187193
(loc, InterfaceDeclaration stuff)
@@ -1321,6 +1327,16 @@ class ['loc] mapper =
13211327
else
13221328
{ value; raw; comments = comments' }
13231329

1330+
method export_assignment _loc (assign : ('loc, 'loc) Ast.Statement.ExportAssignment.t) =
1331+
let open Ast.Statement.ExportAssignment in
1332+
let { expression = expr; comments } = assign in
1333+
let expr' = this#expression expr in
1334+
let comments' = this#syntax_opt comments in
1335+
if expr == expr' && comments == comments' then
1336+
assign
1337+
else
1338+
{ expression = expr'; comments = comments' }
1339+
13241340
method expression_statement _loc (stmt : ('loc, 'loc) Ast.Statement.Expression.t) =
13251341
let open Ast.Statement.Expression in
13261342
let { expression = expr; directive; comments } = stmt in
@@ -2387,6 +2403,43 @@ class ['loc] mapper =
23872403
else
23882404
{ value; raw; comments = comments' }
23892405

2406+
method import_equals_declaration
2407+
_loc (decl : ('loc, 'loc) Ast.Statement.ImportEqualsDeclaration.t) =
2408+
let open Ast.Statement.ImportEqualsDeclaration in
2409+
let { id = ident; module_reference; import_kind; is_export; comments } = decl in
2410+
let ident' =
2411+
let open Ast.Statement.ImportDeclaration in
2412+
match import_kind with
2413+
| ImportType
2414+
| ImportTypeof ->
2415+
this#binding_type_identifier ident
2416+
| ImportValue -> this#pattern_identifier ~kind:Ast.Variable.Let ident
2417+
in
2418+
let module_reference' = this#import_equals_module_reference module_reference in
2419+
let comments' = this#syntax_opt comments in
2420+
if ident == ident' && module_reference == module_reference' && comments == comments' then
2421+
decl
2422+
else
2423+
{
2424+
id = ident';
2425+
module_reference = module_reference';
2426+
import_kind;
2427+
is_export;
2428+
comments = comments';
2429+
}
2430+
2431+
method import_equals_module_reference
2432+
(ref : ('loc, 'loc) Ast.Statement.ImportEqualsDeclaration.module_reference) =
2433+
let open Ast.Statement.ImportEqualsDeclaration in
2434+
match ref with
2435+
| ExternalModuleReference (annot, lit) ->
2436+
let lit' = this#string_literal lit in
2437+
if lit == lit' then
2438+
ref
2439+
else
2440+
ExternalModuleReference (annot, lit')
2441+
| Identifier ident -> id this#generic_identifier_type ident ref (fun ident -> Identifier ident)
2442+
23902443
method import_attributes
23912444
_loc (attrs : ('loc, 'loc) Ast.Statement.ImportDeclaration.import_attribute list) =
23922445
map_list this#import_attribute attrs

src/parser/flow_ast_utils.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,9 @@ let acceptable_statement_in_declaration_context ~in_declare_namespace =
447447
| DeclareVariable _
448448
| Empty _
449449
| EnumDeclaration _
450+
| ExportAssignment _
450451
| ExportNamedDeclaration { ExportNamedDeclaration.export_kind = ExportType; _ }
452+
| ImportEqualsDeclaration _
451453
| InterfaceDeclaration _
452454
| OpaqueType _
453455
| TypeAlias _ ->
@@ -486,13 +488,15 @@ let rec is_type_only_declaration_statement (_, stmt') =
486488
| Debugger _
487489
| DoWhile _
488490
| EnumDeclaration _
491+
| ExportAssignment _
489492
| ExportDefaultDeclaration _
490493
| Expression _
491494
| For _
492495
| ForIn _
493496
| ForOf _
494497
| FunctionDeclaration _
495498
| If _
499+
| ImportEqualsDeclaration _
496500
| Labeled _
497501
| Match _
498502
| RecordDeclaration _

src/parser/parser_flow.ml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,11 @@ let check_for_duplicate_exports =
143143
| DeclareExportDeclaration _ | DeclareFunction _ | DeclareInterface _ | DeclareModule _
144144
| DeclareModuleExports _ | DeclareNamespace _ | DeclareTypeAlias _ | DeclareOpaqueType _
145145
| DeclareVariable _ | DoWhile _ | Empty _ | ExportDefaultDeclaration _
146-
| ExportNamedDeclaration _ | Expression _ | For _ | ForIn _ | ForOf _
146+
| ExportNamedDeclaration _ | ExportAssignment _ | Expression _ | For _ | ForIn _
147+
| ForOf _
147148
| FunctionDeclaration { Function.id = None; _ }
148-
| If _ | ImportDeclaration _ | Labeled _ | Match _ | Return _ | Switch _ | Throw _
149-
| Try _ | While _ | With _ ))
149+
| If _ | ImportDeclaration _ | ImportEqualsDeclaration _ | Labeled _ | Match _
150+
| Return _ | Switch _ | Throw _ | Try _ | While _ | With _ ))
150151
) ->
151152
(* these don't export names -- some are invalid, but the AST allows them *)
152153
seen)
@@ -166,10 +167,11 @@ let check_for_duplicate_exports =
166167
| DeclareComponent _ | DeclareEnum _ | DeclareExportDeclaration _ | DeclareFunction _
167168
| DeclareInterface _ | DeclareModule _ | DeclareModuleExports _ | DeclareNamespace _
168169
| DeclareTypeAlias _ | DeclareOpaqueType _ | DeclareVariable _ | DoWhile _ | Empty _
169-
| EnumDeclaration _ | Expression _ | For _ | ForIn _ | ForOf _ | FunctionDeclaration _
170-
| ComponentDeclaration _ | If _ | ImportDeclaration _ | InterfaceDeclaration _ | Labeled _
171-
| Match _ | RecordDeclaration _ | Return _ | Switch _ | Throw _ | Try _ | TypeAlias _
172-
| OpaqueType _ | VariableDeclaration _ | While _ | With _ ))
170+
| EnumDeclaration _ | ExportAssignment _ | Expression _ | For _ | ForIn _ | ForOf _
171+
| FunctionDeclaration _ | ComponentDeclaration _ | If _ | ImportDeclaration _
172+
| ImportEqualsDeclaration _ | InterfaceDeclaration _ | Labeled _ | Match _
173+
| RecordDeclaration _ | Return _ | Switch _ | Throw _ | Try _ | TypeAlias _ | OpaqueType _
174+
| VariableDeclaration _ | While _ | With _ ))
173175
) ->
174176
seen
175177
in

0 commit comments

Comments
 (0)