@@ -26,6 +26,7 @@ use hhbc::ModuleName;
2626use hhbc:: ParamEntry ;
2727use hhbc:: StringId ;
2828use hhbc:: StringIdMap ;
29+ use hhbc:: TParamInfo ;
2930use hhbc:: TypedValue ;
3031use hhvm_types_ffi:: Attr ;
3132use log:: trace;
@@ -321,6 +322,7 @@ fn assemble_typedef(token_iter: &mut Lexer<'_>, case_type: bool) -> Result<hhbc:
321322
322323fn assemble_class ( token_iter : & mut Lexer < ' _ > , adata : & AdataMap ) -> Result < hhbc:: Class > {
323324 parse ! ( token_iter, ".class"
325+ <tparams: assemble_tparams( ) >
324326 <upper_bounds: assemble_upper_bounds( ) >
325327 <attr: assemble_special_and_user_attrs( ) >
326328 <name: assemble_class_name( ) >
@@ -372,6 +374,7 @@ fn assemble_class(token_iter: &mut Lexer<'_>, adata: &AdataMap) -> Result<hhbc::
372374 ctx_constants : ctx_constants. into ( ) ,
373375 requirements : requirements. into ( ) ,
374376 upper_bounds : upper_bounds. into ( ) ,
377+ tparams : tparams. into ( ) ,
375378 doc_comment,
376379 flags,
377380 } ;
@@ -477,7 +480,7 @@ fn assemble_const_or_type_const(
477480fn assemble_method ( token_iter : & mut Lexer < ' _ > , adata : & AdataMap ) -> Result < hhbc:: Method > {
478481 let method_tok = token_iter. peek ( ) . copied ( ) ;
479482 token_iter. expect_str ( Token :: is_decl, ".method" ) ?;
480- let shadowed_tparams = assemble_shadowed_tparams ( token_iter) ?;
483+ let tparam_info = assemble_tparam_info ( token_iter) ?;
481484 let upper_bounds = assemble_upper_bounds ( token_iter) ?;
482485 let ( attrs, attributes) = assemble_special_and_user_attrs ( token_iter) ?;
483486 let span = assemble_span ( token_iter) ?;
@@ -494,7 +497,7 @@ fn assemble_method(token_iter: &mut Lexer<'_>, adata: &AdataMap) -> Result<hhbc:
494497 attrs,
495498 params,
496499 return_type,
497- shadowed_tparams ,
500+ tparam_info ,
498501 upper_bounds,
499502 span,
500503 ) ?;
@@ -510,19 +513,28 @@ fn assemble_method(token_iter: &mut Lexer<'_>, adata: &AdataMap) -> Result<hhbc:
510513 } )
511514}
512515
513- fn assemble_shadowed_tparams ( token_iter : & mut Lexer < ' _ > ) -> Result < Vec < ClassName > > {
514- token_iter. expect ( Token :: is_open_curly) ?;
515- let mut stp = Vec :: new ( ) ;
516- while token_iter. peek_is ( Token :: is_identifier) {
517- stp. push ( ClassName :: intern (
518- token_iter. expect ( Token :: is_identifier) ?. as_str ( ) ?,
519- ) ) ;
520- if !token_iter. peek_is ( Token :: is_close_curly) {
521- token_iter. expect ( Token :: is_comma) ?;
522- }
523- }
524- token_iter. expect ( Token :: is_close_curly) ?;
525- Ok ( stp)
516+ fn parse_bool ( token_iter : & mut Lexer < ' _ > ) -> Result < bool > {
517+ let tok = token_iter. expect ( Token :: is_identifier) ?;
518+ let id = tok. as_str ( ) ?;
519+ let b = id. parse ( ) ?;
520+ Ok ( b)
521+ }
522+
523+ fn assemble_single_tparam_info ( token_iter : & mut Lexer < ' _ > ) -> Result < TParamInfo > {
524+ parse ! ( token_iter, "[" <name: assemble_class_name( ) > <shadows_class_tparam: parse_bool> "]" ) ;
525+ Ok ( TParamInfo {
526+ name,
527+ shadows_class_tparam,
528+ } )
529+ }
530+
531+ fn assemble_tparam_info ( token_iter : & mut Lexer < ' _ > ) -> Result < Vec < TParamInfo > > {
532+ Ok ( if token_iter. peek_is ( Token :: is_lt) {
533+ parse ! ( token_iter, "<" <tparams: assemble_single_tparam_info( ) , * > ">" ) ;
534+ tparams
535+ } else {
536+ Vec :: new ( )
537+ } )
526538}
527539
528540fn assemble_method_flags ( token_iter : & mut Lexer < ' _ > ) -> Result < hhbc:: MethodFlags > {
@@ -1025,6 +1037,7 @@ where
10251037/// .function {upper bounds} [special_and_user_attrs] (span) <type_info> name (params) flags? {body}
10261038fn assemble_function ( token_iter : & mut Lexer < ' _ > , adata : & AdataMap ) -> Result < hhbc:: Function > {
10271039 token_iter. expect_str ( Token :: is_decl, ".function" ) ?;
1040+ let tparam_info = assemble_tparam_info ( token_iter) ?;
10281041 let upper_bounds = assemble_upper_bounds ( token_iter) ?;
10291042 // Special and user attrs may or may not be specified. If not specified, no [] printed
10301043 let ( attrs, attributes) = assemble_special_and_user_attrs ( token_iter) ?;
@@ -1040,7 +1053,6 @@ fn assemble_function(token_iter: &mut Lexer<'_>, adata: &AdataMap) -> Result<hhb
10401053 let mut decl_map = DeclMap :: default ( ) ;
10411054 let params = assemble_params ( token_iter, & mut decl_map) ?;
10421055 let flags = assemble_function_flags ( name, token_iter) ?;
1043- let shadowed_tparams = Default :: default ( ) ;
10441056 let body = assemble_body (
10451057 token_iter,
10461058 & mut decl_map,
@@ -1049,7 +1061,7 @@ fn assemble_function(token_iter: &mut Lexer<'_>, adata: &AdataMap) -> Result<hhb
10491061 attrs,
10501062 params,
10511063 return_type,
1052- shadowed_tparams ,
1064+ tparam_info ,
10531065 upper_bounds,
10541066 span,
10551067 ) ?;
@@ -1105,6 +1117,15 @@ fn assemble_upper_bounds(token_iter: &mut Lexer<'_>) -> Result<Vec<hhbc::UpperBo
11051117 Ok ( ubs)
11061118}
11071119
1120+ fn assemble_tparams ( token_iter : & mut Lexer < ' _ > ) -> Result < Vec < ClassName > > {
1121+ Ok ( if token_iter. peek_is ( Token :: is_lt) {
1122+ parse ! ( token_iter, "<" <tparams: assemble_class_name( ) , * > ">" ) ;
1123+ tparams
1124+ } else {
1125+ Vec :: new ( )
1126+ } )
1127+ }
1128+
11081129/// Ex: (T as <"HH\\int" "HH\\int" upper_bound>)
11091130fn assemble_upper_bound ( token_iter : & mut Lexer < ' _ > ) -> Result < hhbc:: UpperBound > {
11101131 parse ! ( token_iter, "(" <id: id> "as" <tis: assemble_type_info( TypeInfoKind :: NotEnumOrTypeDef ) , * > ")" ) ;
@@ -1376,7 +1397,7 @@ fn assemble_body(
13761397 attrs : hhbc:: Attr ,
13771398 params : Vec < ParamEntry > ,
13781399 return_type : Maybe < hhbc:: TypeInfo > ,
1379- shadowed_tparams : Vec < ClassName > ,
1400+ tparam_info : Vec < TParamInfo > ,
13801401 upper_bounds : Vec < hhbc:: UpperBound > ,
13811402 span : hhbc:: Span ,
13821403) -> Result < hhbc:: Body > {
@@ -1438,7 +1459,7 @@ fn assemble_body(
14381459 is_memoize_wrapper_lsb,
14391460 doc_comment,
14401461 return_type,
1441- shadowed_tparams : shadowed_tparams . into ( ) ,
1462+ tparam_info : tparam_info . into ( ) ,
14421463 upper_bounds : upper_bounds. into ( ) ,
14431464 span,
14441465 repr : hhbc:: BcRepr {
0 commit comments