Skip to content

Commit

Permalink
[parser] Parse import.meta
Browse files Browse the repository at this point in the history
Summary:
Allows parsing of `import.meta`, which is in the latest standard (from ES2020). While we don't type-check it or other `MetaProperty`s (e.g. `new.target`), at least it's not a parse error so someone can just use `$FlowFixMe` now.

There was a PR for this but it was 3 years old, didn't have parser tests, so I just implemented from scratch myself here instead.

Fixes #6913
Closes #6958

Changelog: [feature] Added parser support for `import.meta`

Reviewed By: mroch

Differential Revision: D30716916

fbshipit-source-id: eb5c5ec53d34d46c228e89137d6a4da8d0839e84
  • Loading branch information
gkz authored and facebook-github-bot committed Sep 2, 2021
1 parent 39f67db commit 0851b3e
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 11 deletions.
51 changes: 41 additions & 10 deletions src/parser/expression_parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ module Expression
comments = _;
} ) ->
false
| ( _,
MetaProperty
{
MetaProperty.meta = (_, { Identifier.name = "import"; comments = _ });
property = (_, { Identifier.name = "meta"; comments = _ });
comments = _;
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
| (_, Array _)
| (_, Identifier _)
Expand Down Expand Up @@ -258,6 +266,14 @@ module Expression
comments = _;
} ) ->
false
| ( _,
MetaProperty
{
MetaProperty.meta = (_, { Identifier.name = "import"; comments = _ });
property = (_, { Identifier.name = "meta"; comments = _ });
comments = _;
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
| (_, Identifier _)
| (_, Member _)
Expand Down Expand Up @@ -677,17 +693,32 @@ module Expression
with_loc
(fun env ->
let leading = Peek.comments env in
let start_loc = Peek.loc env in
Expect.token env T_IMPORT;
let leading_arg = Peek.comments env in
Expect.token env T_LPAREN;
let argument = add_comments (assignment (with_no_in false env)) ~leading:leading_arg in
Expect.token env T_RPAREN;
let trailing = Eat.trailing_comments env in
Expression.Import
{
Expression.Import.argument;
comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing ();
})
if Eat.maybe env T_PERIOD then (
(* import.meta *)
let import_ident = Flow_ast_utils.ident_of_source (start_loc, "import") in
let meta_loc = Peek.loc env in
Expect.identifier env "meta";
let meta_ident = Flow_ast_utils.ident_of_source (meta_loc, "meta") in
let trailing = Eat.trailing_comments env in
Expression.MetaProperty
{
Expression.MetaProperty.meta = import_ident;
property = meta_ident;
comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing ();
}
) else
let leading_arg = Peek.comments env in
Expect.token env T_LPAREN;
let argument = add_comments (assignment (with_no_in false env)) ~leading:leading_arg in
Expect.token env T_RPAREN;
let trailing = Eat.trailing_comments env in
Expression.Import
{
Expression.Import.argument;
comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing ();
})
env

and call_cover ?(allow_optional_chain = true) ?(in_optional_chain = false) env start_loc left =
Expand Down
4 changes: 3 additions & 1 deletion src/parser/parser_flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ module rec Parse : PARSER = struct
error_on_decorators env decorators;
let statement =
match Peek.ith_token ~i:1 env with
| T_LPAREN -> Statement.expression env
| T_LPAREN (* import(...) *)
| T_PERIOD (* import.meta *) ->
Statement.expression env
| _ -> Statement.import_declaration env
in
statement
Expand Down
1 change: 1 addition & 0 deletions src/parser/test/flow/meta_property/import_meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.meta;
35 changes: 35 additions & 0 deletions src/parser/test/flow/meta_property/import_meta.tree.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"type":"Program",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":12}},
"range":[0,12],
"body":[
{
"type":"ExpressionStatement",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":12}},
"range":[0,12],
"expression":{
"type":"MetaProperty",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"range":[0,11],
"meta":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":6}},
"range":[0,6],
"name":"import",
"typeAnnotation":null,
"optional":false
},
"property":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":11}},
"range":[7,11],
"name":"meta",
"typeAnnotation":null,
"optional":false
}
},
"directive":null
}
],
"comments":[]
}
1 change: 1 addition & 0 deletions src/parser/test/flow/meta_property/import_meta_assign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.meta = 1;
54 changes: 54 additions & 0 deletions src/parser/test/flow/meta_property/import_meta_assign.tree.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"errors":[
{
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"message":"Invalid left-hand side in assignment"
}
],
"type":"Program",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":16}},
"range":[0,16],
"body":[
{
"type":"ExpressionStatement",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":16}},
"range":[0,16],
"expression":{
"type":"AssignmentExpression",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":15}},
"range":[0,15],
"operator":"=",
"left":{
"type":"MetaProperty",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"range":[0,11],
"meta":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":6}},
"range":[0,6],
"name":"import",
"typeAnnotation":null,
"optional":false
},
"property":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":11}},
"range":[7,11],
"name":"meta",
"typeAnnotation":null,
"optional":false
}
},
"right":{
"type":"Literal",
"loc":{"source":null,"start":{"line":1,"column":14},"end":{"line":1,"column":15}},
"range":[14,15],
"value":1,
"raw":"1"
}
},
"directive":null
}
],
"comments":[]
}
1 change: 1 addition & 0 deletions src/parser/test/flow/meta_property/import_not_meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.foo;
41 changes: 41 additions & 0 deletions src/parser/test/flow/meta_property/import_not_meta.tree.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"errors":[
{
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":10}},
"message":"Unexpected identifier, expected the identifier `meta`"
}
],
"type":"Program",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"range":[0,11],
"body":[
{
"type":"ExpressionStatement",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"range":[0,11],
"expression":{
"type":"MetaProperty",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":10}},
"range":[0,10],
"meta":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":6}},
"range":[0,6],
"name":"import",
"typeAnnotation":null,
"optional":false
},
"property":{
"type":"Identifier",
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":10}},
"range":[7,10],
"name":"meta",
"typeAnnotation":null,
"optional":false
}
},
"directive":null
}
],
"comments":[]
}

0 comments on commit 0851b3e

Please sign in to comment.