Skip to content

Commit

Permalink
Add parsing support for new trait resolution syntax
Browse files Browse the repository at this point in the history
Summary:
Adds parsing support for the syntax:
```
class C {
  use T1, T2;

  public function animal(): void = T2::animal;
}
```

Reviewed By: jamesjwu

Differential Revision: D10441217

fbshipit-source-id: 1e3c4e9dad6d4ed93966cf9972a0b11d11257152
  • Loading branch information
vassilmladenov authored and hhvm-bot committed Oct 19, 2018
1 parent 326ecf0 commit 1d9da08
Show file tree
Hide file tree
Showing 21 changed files with 569 additions and 16 deletions.
3 changes: 3 additions & 0 deletions hphp/hack/src/facts/flatten_smart_constructors.ml
Expand Up @@ -105,6 +105,9 @@ module WithOp(Op : Op_S) = struct
let make_methodish_declaration arg0 arg1 arg2 arg3 state =
if Op.is_zero arg0 && Op.is_zero arg1 && Op.is_zero arg2 && Op.is_zero arg3 then state, Op.zero
else state, Op.flatten [arg0; arg1; arg2; arg3]
let make_methodish_trait_resolution arg0 arg1 arg2 arg3 arg4 state =
if Op.is_zero arg0 && Op.is_zero arg1 && Op.is_zero arg2 && Op.is_zero arg3 && Op.is_zero arg4 then state, Op.zero
else state, Op.flatten [arg0; arg1; arg2; arg3; arg4]
let make_classish_declaration arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 state =
if Op.is_zero arg0 && Op.is_zero arg1 && Op.is_zero arg2 && Op.is_zero arg3 && Op.is_zero arg4 && Op.is_zero arg5 && Op.is_zero arg6 && Op.is_zero arg7 && Op.is_zero arg8 && Op.is_zero arg9 then state, Op.zero
else state, Op.flatten [arg0; arg1; arg2; arg3; arg4; arg5; arg6; arg7; arg8; arg9]
Expand Down
45 changes: 45 additions & 0 deletions hphp/hack/src/hackfmt/hack_format.ml
Expand Up @@ -446,6 +446,51 @@ let rec t (env: Env.t) (node: Syntax.t) : Doc.t =
t env semi;
Newline;
]
| Syntax.MethodishTraitResolution {
methodish_trait_attribute = attr;
methodish_trait_function_decl_header = func_decl;
methodish_trait_equal = equal;
methodish_trait_name = name;
methodish_trait_semicolon = semi } ->
Concat [
t env attr;
when_present attr newline;
(
let fn_name, args_and_where = match Syntax.syntax func_decl with
| Syntax.FunctionDeclarationHeader {
function_modifiers = modifiers;
function_keyword = kw;
function_ampersand = amp;
function_name = name;
function_type_parameter_list = type_params;
function_left_paren = leftp;
function_parameter_list = params;
function_right_paren = rightp;
function_colon = colon;
function_type = ret_type;
function_where_clause = where } ->
Concat (
transform_fn_decl_name env
modifiers
kw
amp
name
type_params
leftp
),
transform_fn_decl_args env params rightp colon ret_type where
| _ -> failwith "Expected FunctionDeclarationHeader"
in
Concat [
Span [fn_name];
args_and_where;
]
);
t env equal;
t env name;
t env semi;
Newline;
]
| Syntax.ClassishDeclaration {
classish_attribute = attr;
classish_modifiers = modifiers;
Expand Down
9 changes: 9 additions & 0 deletions hphp/hack/src/parser/full_fidelity_declaration_parser.ml
Expand Up @@ -1719,6 +1719,15 @@ module WithExpressionAndStatementAndTypeParser
let (parser, missing) = Make.missing parser1 (pos parser) in
let (parser, semicolon) = Make.token parser token in
Make.methodish_declaration parser attribute_spec header missing semicolon
| Equal ->
let (parser, equal) = assert_token parser Equal in
let (parser, name) =
let (parser, qualifier) = parse_qualified_name_type parser in
let (parser, cc_token) = require_coloncolon parser in
let (parser, name) = require_token_one_of parser [Name; Construct] SyntaxError.error1004 in
Make.scope_resolution_expression parser qualifier cc_token name in
let (parser, semi) = require_semicolon parser in
Make.methodish_trait_resolution parser attribute_spec header equal name semi
| _ ->
(* ERROR RECOVERY: We expected either a block or a semicolon; we got
neither. Use the offending token as the body of the method.
Expand Down
72 changes: 72 additions & 0 deletions hphp/hack/src/parser/full_fidelity_syntax.ml
Expand Up @@ -84,6 +84,7 @@ module WithToken(Token: TokenType) = struct
| WhereClause _ -> SyntaxKind.WhereClause
| WhereConstraint _ -> SyntaxKind.WhereConstraint
| MethodishDeclaration _ -> SyntaxKind.MethodishDeclaration
| MethodishTraitResolution _ -> SyntaxKind.MethodishTraitResolution
| ClassishDeclaration _ -> SyntaxKind.ClassishDeclaration
| ClassishBody _ -> SyntaxKind.ClassishBody
| TraitUsePrecedenceItem _ -> SyntaxKind.TraitUsePrecedenceItem
Expand Down Expand Up @@ -266,6 +267,7 @@ module WithToken(Token: TokenType) = struct
let is_where_clause = has_kind SyntaxKind.WhereClause
let is_where_constraint = has_kind SyntaxKind.WhereConstraint
let is_methodish_declaration = has_kind SyntaxKind.MethodishDeclaration
let is_methodish_trait_resolution = has_kind SyntaxKind.MethodishTraitResolution
let is_classish_declaration = has_kind SyntaxKind.ClassishDeclaration
let is_classish_body = has_kind SyntaxKind.ClassishBody
let is_trait_use_precedence_item = has_kind SyntaxKind.TraitUsePrecedenceItem
Expand Down Expand Up @@ -724,6 +726,19 @@ module WithToken(Token: TokenType) = struct
let acc = f acc methodish_function_body in
let acc = f acc methodish_semicolon in
acc
| MethodishTraitResolution {
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
} ->
let acc = f acc methodish_trait_attribute in
let acc = f acc methodish_trait_function_decl_header in
let acc = f acc methodish_trait_equal in
let acc = f acc methodish_trait_name in
let acc = f acc methodish_trait_semicolon in
acc
| ClassishDeclaration {
classish_attribute;
classish_modifiers;
Expand Down Expand Up @@ -2569,6 +2584,19 @@ module WithToken(Token: TokenType) = struct
methodish_function_body;
methodish_semicolon;
]
| MethodishTraitResolution {
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
} -> [
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
]
| ClassishDeclaration {
classish_attribute;
classish_modifiers;
Expand Down Expand Up @@ -4415,6 +4443,19 @@ module WithToken(Token: TokenType) = struct
"methodish_function_body";
"methodish_semicolon";
]
| MethodishTraitResolution {
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
} -> [
"methodish_trait_attribute";
"methodish_trait_function_decl_header";
"methodish_trait_equal";
"methodish_trait_name";
"methodish_trait_semicolon";
]
| ClassishDeclaration {
classish_attribute;
classish_modifiers;
Expand Down Expand Up @@ -6340,6 +6381,20 @@ module WithToken(Token: TokenType) = struct
methodish_function_body;
methodish_semicolon;
}
| (SyntaxKind.MethodishTraitResolution, [
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
]) ->
MethodishTraitResolution {
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
}
| (SyntaxKind.ClassishDeclaration, [
classish_attribute;
classish_modifiers;
Expand Down Expand Up @@ -8465,6 +8520,23 @@ module WithToken(Token: TokenType) = struct
let value = ValueBuilder.value_from_syntax syntax in
make syntax value

let make_methodish_trait_resolution
methodish_trait_attribute
methodish_trait_function_decl_header
methodish_trait_equal
methodish_trait_name
methodish_trait_semicolon
=
let syntax = MethodishTraitResolution {
methodish_trait_attribute;
methodish_trait_function_decl_header;
methodish_trait_equal;
methodish_trait_name;
methodish_trait_semicolon;
} in
let value = ValueBuilder.value_from_syntax syntax in
make syntax value

let make_classish_declaration
classish_attribute
classish_modifiers
Expand Down
2 changes: 2 additions & 0 deletions hphp/hack/src/parser/full_fidelity_syntax_kind.ml
Expand Up @@ -45,6 +45,7 @@ type t =
| WhereClause
| WhereConstraint
| MethodishDeclaration
| MethodishTraitResolution
| ClassishDeclaration
| ClassishBody
| TraitUsePrecedenceItem
Expand Down Expand Up @@ -221,6 +222,7 @@ let to_string kind =
| WhereClause -> "where_clause"
| WhereConstraint -> "where_constraint"
| MethodishDeclaration -> "methodish_declaration"
| MethodishTraitResolution -> "methodish_trait_resolution"
| ClassishDeclaration -> "classish_declaration"
| ClassishBody -> "classish_body"
| TraitUsePrecedenceItem -> "trait_use_precedence_item"
Expand Down
31 changes: 23 additions & 8 deletions hphp/hack/src/parser/full_fidelity_syntax_type.ml
Expand Up @@ -276,6 +276,13 @@ module MakeSyntaxType(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
; methodish_function_body : t
; methodish_semicolon : t
}
| MethodishTraitResolution of
{ methodish_trait_attribute : t
; methodish_trait_function_decl_header : t
; methodish_trait_equal : t
; methodish_trait_name : t
; methodish_trait_semicolon : t
}
| ClassishDeclaration of
{ classish_attribute : t
; classish_modifiers : t
Expand Down Expand Up @@ -1277,14 +1284,15 @@ module MakeValidated(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
| ParamParameterDeclaration of parameter_declaration
| ParamVariadicParameter of variadic_parameter
and class_body_declaration =
| BodyProperty of property_declaration
| BodyMethodish of methodish_declaration
| BodyRequireClause of require_clause
| BodyConst of const_declaration
| BodyTypeConst of type_const_declaration
| BodyXHPChildren of xhp_children_declaration
| BodyXHPCategory of xhp_category_declaration
| BodyXHPClassAttribute of xhp_class_attribute_declaration
| BodyProperty of property_declaration
| BodyMethodish of methodish_declaration
| BodyMethodishTraitResolution of methodish_trait_resolution
| BodyRequireClause of require_clause
| BodyConst of const_declaration
| BodyTypeConst of type_const_declaration
| BodyXHPChildren of xhp_children_declaration
| BodyXHPCategory of xhp_category_declaration
| BodyXHPClassAttribute of xhp_class_attribute_declaration
and statement =
| StmtInclusionDirective of inclusion_directive
| StmtCompound of compound_statement
Expand Down Expand Up @@ -1570,6 +1578,13 @@ module MakeValidated(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
; methodish_function_body: compound_statement option value
; methodish_semicolon: Token.t option value
}
and methodish_trait_resolution =
{ methodish_trait_attribute: attribute_specification option value
; methodish_trait_function_decl_header: function_declaration_header value
; methodish_trait_equal: Token.t value
; methodish_trait_name: specifier value
; methodish_trait_semicolon: Token.t value
}
and classish_declaration =
{ classish_attribute: attribute_specification option value
; classish_modifiers: Token.t listesque value
Expand Down
38 changes: 30 additions & 8 deletions hphp/hack/src/parser/full_fidelity_validated_syntax.ml
Expand Up @@ -354,6 +354,7 @@ module Make(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
match Syntax.syntax x with
| Syntax.PropertyDeclaration _ -> tag validate_property_declaration (fun x -> BodyProperty x) x
| Syntax.MethodishDeclaration _ -> tag validate_methodish_declaration (fun x -> BodyMethodish x) x
| Syntax.MethodishTraitResolution _ -> tag validate_methodish_trait_resolution (fun x -> BodyMethodishTraitResolution x) x
| Syntax.RequireClause _ -> tag validate_require_clause (fun x -> BodyRequireClause x) x
| Syntax.ConstDeclaration _ -> tag validate_const_declaration (fun x -> BodyConst x) x
| Syntax.TypeConstDeclaration _ -> tag validate_type_const_declaration (fun x -> BodyTypeConst x) x
Expand All @@ -363,14 +364,15 @@ module Make(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
| s -> aggregation_fail Def.ClassBodyDeclaration s
and invalidate_class_body_declaration : class_body_declaration invalidator = fun (value, thing) ->
match thing with
| BodyProperty thing -> invalidate_property_declaration (value, thing)
| BodyMethodish thing -> invalidate_methodish_declaration (value, thing)
| BodyRequireClause thing -> invalidate_require_clause (value, thing)
| BodyConst thing -> invalidate_const_declaration (value, thing)
| BodyTypeConst thing -> invalidate_type_const_declaration (value, thing)
| BodyXHPChildren thing -> invalidate_xhp_children_declaration (value, thing)
| BodyXHPCategory thing -> invalidate_xhp_category_declaration (value, thing)
| BodyXHPClassAttribute thing -> invalidate_xhp_class_attribute_declaration (value, thing)
| BodyProperty thing -> invalidate_property_declaration (value, thing)
| BodyMethodish thing -> invalidate_methodish_declaration (value, thing)
| BodyMethodishTraitResolution thing -> invalidate_methodish_trait_resolution (value, thing)
| BodyRequireClause thing -> invalidate_require_clause (value, thing)
| BodyConst thing -> invalidate_const_declaration (value, thing)
| BodyTypeConst thing -> invalidate_type_const_declaration (value, thing)
| BodyXHPChildren thing -> invalidate_xhp_children_declaration (value, thing)
| BodyXHPCategory thing -> invalidate_xhp_category_declaration (value, thing)
| BodyXHPClassAttribute thing -> invalidate_xhp_class_attribute_declaration (value, thing)
and validate_statement : statement validator = fun x ->
match Syntax.syntax x with
| Syntax.InclusionDirective _ -> tag validate_inclusion_directive (fun x -> StmtInclusionDirective x) x
Expand Down Expand Up @@ -1113,6 +1115,26 @@ module Make(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
}
; Syntax.value = v
}
and validate_methodish_trait_resolution : methodish_trait_resolution validator = function
| { Syntax.syntax = Syntax.MethodishTraitResolution x; value = v } -> v,
{ methodish_trait_semicolon = validate_token x.methodish_trait_semicolon
; methodish_trait_name = validate_specifier x.methodish_trait_name
; methodish_trait_equal = validate_token x.methodish_trait_equal
; methodish_trait_function_decl_header = validate_function_declaration_header x.methodish_trait_function_decl_header
; methodish_trait_attribute = validate_option_with (validate_attribute_specification) x.methodish_trait_attribute
}
| s -> validation_fail (Some SyntaxKind.MethodishTraitResolution) s
and invalidate_methodish_trait_resolution : methodish_trait_resolution invalidator = fun (v, x) ->
{ Syntax.syntax =
Syntax.MethodishTraitResolution
{ methodish_trait_attribute = invalidate_option_with (invalidate_attribute_specification) x.methodish_trait_attribute
; methodish_trait_function_decl_header = invalidate_function_declaration_header x.methodish_trait_function_decl_header
; methodish_trait_equal = invalidate_token x.methodish_trait_equal
; methodish_trait_name = invalidate_specifier x.methodish_trait_name
; methodish_trait_semicolon = invalidate_token x.methodish_trait_semicolon
}
; Syntax.value = v
}
and validate_classish_declaration : classish_declaration validator = function
| { Syntax.syntax = Syntax.ClassishDeclaration x; value = v } -> v,
{ classish_body = validate_classish_body x.classish_body
Expand Down

0 comments on commit 1d9da08

Please sign in to comment.