Skip to content

Commit

Permalink
Parse generic collection literals
Browse files Browse the repository at this point in the history
Summary: Collection literals can have type arguments = in this diff type of collection name is changed to specifier and expression parser is updated to handle type argument lists after collection name.

Reviewed By: oulgen

Differential Revision: D6096308

fbshipit-source-id: a4e59caf775514041a9d1c7130d8799ab95d03b5
  • Loading branch information
vladima authored and hhvm-bot committed Oct 21, 2017
1 parent 01f0585 commit 93f5998
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 17 deletions.
15 changes: 12 additions & 3 deletions hphp/hack/src/parser/full_fidelity_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,20 @@ and pExpr ?location:(location=TopLevel) : expr parser = fun node env ->
{ vector_intrinsic_keyword = kw
; vector_intrinsic_members = members
; _ }
-> Collection (pos_name kw, couldMap ~f:pAField members env)
| CollectionLiteralExpression
{ collection_literal_name = kw
{ collection_literal_name = collection_name
; collection_literal_initializers = members
; _ }
-> Collection (pos_name kw, couldMap ~f:pAField members env)
; _ } ->
let collection_name =
match syntax collection_name with
| SimpleTypeSpecifier { simple_type_specifier = class_type }
(* TODO: currently type arguments are dropped on the floor,
though they should be properly propagated to the typechecker *)
| GenericTypeSpecifier { generic_class_type = class_type; _ } ->
pos_name class_type
| _ -> pos_name collection_name in
Collection (collection_name, couldMap ~f:pAField members env)

| VarrayIntrinsicExpression { varray_intrinsic_members = members; _ } ->
Varray (couldMap ~f:pExpr members env)
Expand Down
25 changes: 20 additions & 5 deletions hphp/hack/src/parser/full_fidelity_expression_parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ module WithStatementAndDeclAndTypeParser
let parser = { parser with lexer; errors } in
(parser, node)

let is_valid_type_argument_list type_arguments parser0 parser1 =
kind type_arguments = SyntaxKind.TypeArguments
&& List.for_all (fun c -> not (is_missing c)) (children type_arguments)
&& parser0.errors = parser1.errors

let parse_return_type parser =
let type_parser = TypeParser.make parser.lexer
~hhvm_compat_mode:parser.hhvm_compat_mode
Expand Down Expand Up @@ -630,16 +635,15 @@ module WithStatementAndDeclAndTypeParser
and parse_remaining_expression_or_specified_function_call parser term
prefix_kind =
let parser1, type_arguments = parse_generic_type_arguments_opt parser in
if kind type_arguments <> SyntaxKind.TypeArguments
|| List.exists is_missing @@ children type_arguments
|| parser1.errors <> parser.errors
then parse_remaining_binary_expression parser term prefix_kind
else
if is_valid_type_argument_list type_arguments parser parser1
then
let (parser, left, args, right) = parse_expression_list_opt parser1 in
let result = make_function_call_with_type_arguments_expression
term type_arguments left args right
in
parse_remaining_expression parser result
else
parse_remaining_binary_expression parser term prefix_kind

(* checks if t is a prefix unary expression where operator has expected kind
and and operand matched predicate *)
Expand Down Expand Up @@ -1666,7 +1670,18 @@ TODO: This will need to be fixed to allow situations where the qualified name
let name = make_token token in
match peek_token_kind parser with
| LeftBrace ->
let name = make_simple_type_specifier name in
parse_collection_literal_expression parser name
| LessThan ->
let parser1, type_arguments =
parse_generic_type_arguments_opt parser in
if is_valid_type_argument_list type_arguments parser parser1
&& peek_token_kind parser1 = LeftBrace
then
let name = make_generic_type_specifier name type_arguments in
parse_collection_literal_expression parser1 name
else
(parser, make_qualified_name_expression name)
| _ ->
(parser, make_qualified_name_expression name)

Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/src/parser/full_fidelity_syntax_type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,7 @@ module MakeValidated(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
; list_right_paren: Token.t value
}
and collection_literal_expression =
{ collection_literal_name: Token.t value
{ collection_literal_name: specifier value
; collection_literal_left_brace: Token.t value
; collection_literal_initializers: constructor_expression listesque value
; collection_literal_right_brace: Token.t value
Expand Down
4 changes: 2 additions & 2 deletions hphp/hack/src/parser/full_fidelity_validated_syntax.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2454,13 +2454,13 @@ module Make(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
{ collection_literal_right_brace = validate_token x.Syntax.collection_literal_right_brace
; collection_literal_initializers = validate_list_with (validate_constructor_expression) x.Syntax.collection_literal_initializers
; collection_literal_left_brace = validate_token x.Syntax.collection_literal_left_brace
; collection_literal_name = validate_token x.Syntax.collection_literal_name
; collection_literal_name = validate_specifier x.Syntax.collection_literal_name
}
| s -> validation_fail SyntaxKind.CollectionLiteralExpression s
and invalidate_collection_literal_expression : collection_literal_expression invalidator = fun (v, x) ->
{ Syntax.syntax =
Syntax.CollectionLiteralExpression
{ Syntax.collection_literal_name = invalidate_token x.collection_literal_name
{ Syntax.collection_literal_name = invalidate_specifier x.collection_literal_name
; Syntax.collection_literal_left_brace = invalidate_token x.collection_literal_left_brace
; Syntax.collection_literal_initializers = invalidate_list_with (invalidate_constructor_expression) x.collection_literal_initializers
; Syntax.collection_literal_right_brace = invalidate_token x.collection_literal_right_brace
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/src/parser/js/full_fidelity_schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{ "description" :
"Auto-generated JSON schema of the Hack Full Fidelity Parser AST",
"version" : "2017-10-02-0001",
"version" : "2017-10-18-0001",
"trivia" : [
{ "trivia_kind_name" : "WhiteSpace",
"trivia_type_name" : "whitespace" },
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/src/parser/schema/full_fidelity_schema.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

(* If you make changes to the schema that cause it to serialize / deserialize
differently, please update this version number *)
let full_fidelity_schema_version_number = "2017-10-02-0001"
let full_fidelity_schema_version_number = "2017-10-18-0001"
(* TODO: Consider basing the version number on an auto-generated
hash of a file rather than relying on people remembering to update it. *)
(* TODO: It may be worthwhile to investigate how Thrift describes data types
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/src/parser/schema/schema_definition.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ let schema : schema_node list =
; prefix = "collection_literal"
; aggregates = [ Expression; ConstructorExpression; LambdaBody ]
; fields =
[ "name", Token
[ "name", Aggregate Specifier
; "left_brace", Token
; "initializers", ZeroOrMore (Aggregate ConstructorExpression)
; "right_brace", Token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
(expression_statement((rparen))(missing))
(expression_statement((:)(whitespace))(missing))
(expression_statement(collection_literal_expression(
(name)(whitespace))(({))(missing)((})))(missing)
simple_type_specifier((name)(whitespace)))(({))(missing)((})))(missing)
)
)(missing)))))
2 changes: 0 additions & 2 deletions hphp/test/hhcodegen_failing_tests_slow
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ slow/class_type_constant/type_constant4.php
slow/class_type_constant/type_constant6.php
slow/closure/lambda_implicit_this.php
slow/closure/return_types.php
slow/collection_classes/815.php
slow/concat/1578.php
slow/constant/1597.php
slow/constant/casing.php
Expand All @@ -30,7 +29,6 @@ slow/dynamic_variables/1164.php
slow/exceptions/62.php
slow/ext_function/register_postsend_function-simple.php
slow/ext_function/register_shutdown_function-simple.php
slow/ext_mailparse/ext_uudecode.php
slow/ext_misc/ext_misc.php
slow/ext_phar/composer.php
slow/ext_phar/create_tar.php
Expand Down

0 comments on commit 93f5998

Please sign in to comment.