Skip to content
This repository has been archived by the owner on Jun 4, 2019. It is now read-only.

Commit

Permalink
[pfff] parse hh async blocks
Browse files Browse the repository at this point in the history
Summary:
The syntax `async { <body> }` is used to indicate an
 immediately executed short closure (aka lambda). Some AST
 manipulation is required to indicate that the parameter list and
 `==>` portions of the lambda have been omitted.

Test Plan: included test

Reviewers: pieter, mqian, andrewparoski, jezng, jan

Reviewed By: jan

Differential Revision: https://phabricator.fb.com/D1816822

Signature: t1:1816822:1422667074:805bb5a4ce559b0192459ab6015b50df0d9be164
  • Loading branch information
Eugene Letuchy committed Jan 31, 2015
1 parent 409b5ed commit a501646
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 14 deletions.
8 changes: 7 additions & 1 deletion lang_php/analyze/foundation/ast_php_simple_build.ml
Original file line number Diff line number Diff line change
Expand Up @@ -523,10 +523,16 @@ and lambda_def env (l_use, ld) =
and short_lambda_def env def =
{ A.
f_ref = false;
f_name = (A.special "_lambda", wrap def.sl_tok);
f_name = (
A.special "_lambda",
match def.sl_tok with
| Some tok -> wrap tok
| None -> None
);
f_params =
(match def.sl_params with
| SLSingleParam p -> [parameter env p]
| SLParamsOmitted -> []
| SLParams (_, xs, _) ->
let xs = comma_list_dots xs in
List.map (parameter env) xs
Expand Down
3 changes: 2 additions & 1 deletion lang_php/parsing/ast_php.ml
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,13 @@ and short_lambda_def = {
(* "async" is the only valid modifier *)
sl_modifiers: modifier wrap list;
sl_params: short_lambda_params;
sl_tok: tok (* ==> *);
sl_tok: tok (* ==> *) option; (* async { } doesn't use a ==> *)
sl_body: short_lambda_body;
}
and short_lambda_params =
| SLSingleParam of parameter
| SLParams of parameter comma_list_dots paren
| SLParamsOmitted (* for async { } lambdas *)
and short_lambda_body =
| SLExpr of expr
| SLBody of stmt_and_def list brace
Expand Down
3 changes: 2 additions & 1 deletion lang_php/parsing/map_php.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ and map_short_lambda_def { sl_modifiers = v_sl_modifiers;
} =
let v_sl_modifiers = map_of_list (map_wrap map_modifier) v_sl_modifiers in
let v_sl_body = map_short_lambda_body v_sl_body in
let v_sl_tok = map_tok v_sl_tok in
let v_sl_tok = map_of_option map_tok v_sl_tok in
let v_sl_params = map_short_lambda_params v_sl_params in
{
sl_modifiers = v_sl_modifiers;
Expand All @@ -1117,6 +1117,7 @@ and map_short_lambda_params =
| SLParams v1 ->
let v1 = map_paren (map_comma_list_dots map_parameter) v1
in SLParams ((v1))
| SLParamsOmitted -> SLParamsOmitted
and map_short_lambda_body =
function
| SLExpr v1 -> let v1 = map_expr v1 in SLExpr ((v1))
Expand Down
4 changes: 3 additions & 1 deletion lang_php/parsing/meta_ast_php.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,7 @@ and vof_short_lambda_def {
let arg = vof_short_lambda_body v_sl_body in
let bnd = ("sl_body", arg) in
let bnds = bnd :: bnds in
let arg = vof_tok v_sl_tok in
let arg = vof_option vof_tok v_sl_tok in
let bnd = ("sl_tok", arg) in
let bnds = bnd :: bnds in
let arg = vof_short_lambda_params v_sl_params in
Expand All @@ -1181,6 +1181,8 @@ and vof_short_lambda_params =
| SLParams v1 ->
let v1 = vof_paren (vof_comma_list_dots vof_parameter) v1
in Ocaml.VSum (("SLParams", [ v1 ]))
| SLParamsOmitted ->
Ocaml.VSum (("SLParamsOmitted", []))
and vof_short_lambda_body =
function
| SLExpr v1 -> let v1 = vof_expr v1 in Ocaml.VSum (("SLExpr", [ v1 ]))
Expand Down
24 changes: 15 additions & 9 deletions lang_php/parsing/parser_php.mly
Original file line number Diff line number Diff line change
Expand Up @@ -1343,36 +1343,42 @@ lambda_expr:
{
let sl_tok, sl_body = $2 in
let sl_params = SLSingleParam (H.mk_param $1) in
ShortLambda { sl_params; sl_tok = sl_tok; sl_body = sl_body; sl_modifiers = [] }
ShortLambda { sl_params; sl_tok; sl_body; sl_modifiers = [] }
}
| T_ASYNC T_VARIABLE lambda_body
{
let sl_tok, sl_body = $3 in
let sl_params = SLSingleParam (H.mk_param $2) in
ShortLambda { sl_params; sl_tok = sl_tok; sl_body = sl_body;
sl_modifiers = [Async,($1)] }
ShortLambda { sl_params; sl_tok; sl_body; sl_modifiers = [Async,($1)] }
}
| T_LAMBDA_OPAR parameter_list T_LAMBDA_CPAR return_type_opt lambda_body
{
let sl_tok, sl_body = $5 in
let sl_params = SLParams ($1, $2, $3) in
ShortLambda { sl_params; sl_tok = sl_tok; sl_body = sl_body;
sl_modifiers = []; }
ShortLambda { sl_params; sl_tok; sl_body; sl_modifiers = []; }
}
| T_ASYNC T_LAMBDA_OPAR parameter_list T_LAMBDA_CPAR return_type_opt lambda_body
{
let sl_tok, sl_body = $6 in
let sl_params = SLParams ($2, $3, $4) in
ShortLambda { sl_params; sl_tok = sl_tok; sl_body = sl_body;
sl_modifiers = [Async,($1)]; }
ShortLambda { sl_params; sl_tok; sl_body; sl_modifiers = [Async,($1)]; }
}
| T_ASYNC TOBRACE inner_statement_list TCBRACE
{
let sl_body = SLBody ($2, $3, $4) in
ShortLambda { sl_params = SLParamsOmitted;
sl_tok = None;
sl_body;
sl_modifiers = [Async,($1)];
}
}

lambda_body:
| T_DOUBLE_ARROW TOBRACE inner_statement_list TCBRACE { ($1, SLBody ($2, $3, $4)) }
| T_DOUBLE_ARROW TOBRACE inner_statement_list TCBRACE { (Some $1, SLBody ($2, $3, $4)) }
/*(* An explicit case required for when/if awaits become statements, not expr *)
(* | T_DOUBLE_ARROW T_AWAIT expr { ($1, SLExpr (Await ($2, $3))) } *)*/
/*(* see conflicts.txt for why the %prec *)*/
| T_DOUBLE_ARROW expr { ($1, SLExpr $2) }
| T_DOUBLE_ARROW expr { (Some $1, SLExpr $2) }

/*(*----------------------------*)*/
/*(*2 auxillary bis *)*/
Expand Down
4 changes: 3 additions & 1 deletion lang_php/parsing/visitor_php.ml
Original file line number Diff line number Diff line change
Expand Up @@ -370,11 +370,13 @@ and
} =
let arg = v_list (v_wrap v_modifier) v_sl_modifiers in
let arg = v_short_lambda_params v_sl_params in
let arg = v_tok v_sl_tok in let arg = v_short_lambda_body v_sl_body in ()
let arg = v_option v_tok v_sl_tok in
let arg = v_short_lambda_body v_sl_body in ()
and v_short_lambda_params =
function
| SLSingleParam v1 -> let v1 = v_parameter v1 in ()
| SLParams v1 -> let v1 = v_paren (v_comma_list_dots v_parameter) v1 in ()
| SLParamsOmitted -> ()
and v_short_lambda_body =
function
| SLExpr v1 -> let v1 = v_expr v1 in ()
Expand Down
1 change: 1 addition & 0 deletions tests/php/parsing/short_lambda.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function foo(): void {
$func = async $y ==> { return $y + 2; };
$func = $y ==> { return $y - 2; };
$func = async $y ==> { return $y - 2; };
$func = async { return 0; };
$x = Vector { 1,2,3 };
mapp($x, $func);
}
Expand Down

0 comments on commit a501646

Please sign in to comment.