Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parser: add parse-only support for "import.meta" #6958

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 60 additions & 12 deletions src/parser/expression_parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ module Expression
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
| ( _,
MetaProperty
{
MetaProperty.meta = (_, { Identifier.name = "import"; comments = _ });
property = (_, { Identifier.name = "meta"; comments = _ });
comments = _;
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
(* draft spec: https://tc39.github.io/proposal-import-meta/ *)
| (_, Array _)
| (_, Identifier _)
| (_, Member _)
Expand Down Expand Up @@ -255,6 +265,16 @@ module Expression
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
| ( _,
MetaProperty
{
MetaProperty.meta = (_, { Identifier.name = "import"; comments = _ });
property = (_, { Identifier.name = "meta"; comments = _ });
comments = _;
} ) ->
false
(* #sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget *)
(* draft spec: https://tc39.github.io/proposal-import-meta/ *)
| (_, Identifier _)
| (_, Member _)
| (_, MetaProperty _) ->
Expand Down Expand Up @@ -670,21 +690,49 @@ module Expression
super

and import env =
with_loc
(fun env ->
let leading = Peek.comments 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 start_loc = Peek.loc env in
let leading = Peek.comments env in
Expect.token env T_IMPORT;

if Peek.token env = T_PERIOD then (
(* "import.meta" syntax (no other metaproperties are permitted) *)
Expect.token env T_PERIOD;
let meta = Flow_ast_utils.ident_of_source (start_loc, "import") in
match Peek.token env with
| T_IDENTIFIER { raw = "meta"; _ } ->
let property = Parse.identifier env in
let trailing = Eat.trailing_comments env in
Expression.Import
let end_loc = fst property in
let meta_property = let open Expression.MetaProperty in Expression.MetaProperty
{
Expression.Import.argument;
meta;
property;
comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing ();
})
env
} in
(Loc.btwn start_loc end_loc, meta_property)
| T_IDENTIFIER _ ->
error_at env (start_loc, Parse_error.InvalidImportMetaProperty);
Eat.token env;
(start_loc, Expression.Identifier meta)
| _ ->
error_unexpected ~expected:"identifier for `import` metaproperty" env;
Eat.token env;
(start_loc, Expression.Identifier meta)
) else (
(* "import(...)" syntax *)
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
let end_loc = Peek.loc env in
Expect.token env T_RPAREN;
let trailing = Eat.trailing_comments env in
let import = Expression.Import
{
Expression.Import.argument;
comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing ();
} in
(Loc.btwn start_loc end_loc, import)
)

and call_cover ?(allow_optional_chain = true) ?(in_optional_chain = false) env start_loc left =
let left = member_cover ~allow_optional_chain ~in_optional_chain env start_loc left in
Expand Down
2 changes: 2 additions & 0 deletions src/parser/parse_error.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type t =
| InvalidLHSInExponentiation
| InvalidLHSInForIn
| InvalidLHSInForOf
| InvalidImportMetaProperty
| ExpectedPatternFoundExpression
| MultipleDefaultsInSwitch
| NoCatchOrFinally
Expand Down Expand Up @@ -276,6 +277,7 @@ module PP = struct
| InvalidLHSInExponentiation -> "Invalid left-hand side in exponentiation expression"
| InvalidLHSInForIn -> "Invalid left-hand side in for-in"
| InvalidLHSInForOf -> "Invalid left-hand side in for-of"
| InvalidImportMetaProperty -> "The only valid meta property for import is import.meta"
| ExpectedPatternFoundExpression ->
"Expected an object pattern, array pattern, or an identifier but "
^ "found an expression instead"
Expand Down
2 changes: 1 addition & 1 deletion src/parser/parser_flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ 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 | T_PERIOD -> Statement.expression env
| _ -> Statement.import_declaration env
in
statement
Expand Down
3 changes: 3 additions & 0 deletions tests/import_meta/.flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[options]
module.system=haste
no_flowlib=false
50 changes: 50 additions & 0 deletions tests/import_meta/import_meta.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Error ----------------------------------------------------------------------------------------------- import_meta.js:9:1

Not supported. [unsupported-syntax]

9| import.meta;
^^^^^^^^^^^


Error ---------------------------------------------------------------------------------------------- import_meta.js:12:1

Not supported. [unsupported-syntax]

12| import.meta.hello = "world";
^^^^^^^^^^^


Error --------------------------------------------------------------------------------------------- import_meta.js:15:14

Not supported. [unsupported-syntax]

15| const meta = import.meta;
^^^^^^^^^^^


Error ---------------------------------------------------------------------------------- no_assign_to_import_meta.js:4:1

Invalid left-hand side in assignment

4| import.meta = {wat: "wat"}; // parse error
^^^^^^^^^^^


Error ------------------------------------------------------------------------- no_nonidentifier_after_import_dot.js:4:8

Unexpected token `while`, expected identifier for `import` metaproperty

4| import.while; // parse error
^^^^^


Error ----------------------------------------------------------------------------------- no_other_metaproperties.js:4:1

The only valid meta property for import is import.meta

4| import.atem; // parse error
^^^^^^



Found 6 errors
22 changes: 22 additions & 0 deletions tests/import_meta/import_meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @flow

// NOTE: The following tests all currently yield a "Not supported."
// error because Flow does not process MetaProperty expressions at all.
// The comments above each test case describe what the behavior _should_
// be once typechecking is implemented.

// You can access `import.meta` at the root of the module.
import.meta;

// You can write to `import.meta` at the root of the module.
import.meta.hello = "world";

// You can use `import.meta` in a normal expression context.
const meta = import.meta;

// All properties are `mixed`.
(meta.whatever: mixed);
(meta.whatnever: number); // error

// Properties are writable.
meta.writeable = "definitely";
4 changes: 4 additions & 0 deletions tests/import_meta/no_assign_to_import_meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @flow

// You can't assign to it.
import.meta = {wat: "wat"}; // parse error
4 changes: 4 additions & 0 deletions tests/import_meta/no_nonidentifier_after_import_dot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @flow

// If you have "import.SOMETHING", that "SOMETHING" must be an identifier.
import.while; // parse error
4 changes: 4 additions & 0 deletions tests/import_meta/no_other_metaproperties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @flow

// You can't access any other metaproperties on `import`.
import.atem; // parse error