remove coroutine keyword
[hiphop-php.git] / hphp / hack / src / parser / core / type_parser.rs
blob7fa2a41d2d0951dd449389b4c89c2f55269dd2d6
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 use crate::declaration_parser::DeclarationParser;
8 use crate::expression_parser::ExpressionParser;
9 use crate::lexer::Lexer;
10 use crate::parser_env::ParserEnv;
11 use crate::parser_trait::Context;
12 use crate::parser_trait::ParserTrait;
13 use crate::parser_trait::SeparatedListKind;
14 use crate::smart_constructors::{NodeType, SmartConstructors};
15 use parser_core_types::lexable_token::LexableToken;
16 use parser_core_types::syntax_error::{self as Errors, SyntaxError};
17 use parser_core_types::token_kind::TokenKind;
19 pub struct TypeParser<'a, S, T>
20 where
21     S: SmartConstructors<'a, T>,
22     S::R: NodeType,
24     lexer: Lexer<'a, S::Token>,
25     env: ParserEnv,
26     context: Context<'a, S::Token>,
27     errors: Vec<SyntaxError>,
28     sc: S,
31 impl<'a, S, T: Clone> std::clone::Clone for TypeParser<'a, S, T>
32 where
33     S: SmartConstructors<'a, T>,
34     S::R: NodeType,
36     fn clone(&self) -> Self {
37         Self {
38             lexer: self.lexer.clone(),
39             env: self.env.clone(),
40             context: self.context.clone(),
41             errors: self.errors.clone(),
42             sc: self.sc.clone(),
43         }
44     }
47 impl<'a, S, T: Clone> ParserTrait<'a, S, T> for TypeParser<'a, S, T>
48 where
49     S: SmartConstructors<'a, T>,
50     S::R: NodeType,
52     fn make(
53         mut lexer: Lexer<'a, S::Token>,
54         env: ParserEnv,
55         context: Context<'a, S::Token>,
56         errors: Vec<SyntaxError>,
57         sc: S,
58     ) -> Self {
59         lexer.set_in_type(true);
60         Self {
61             lexer,
62             env,
63             context,
64             errors,
65             sc,
66         }
67     }
69     fn into_parts(
70         mut self,
71     ) -> (
72         Lexer<'a, S::Token>,
73         Context<'a, S::Token>,
74         Vec<SyntaxError>,
75         S,
76     ) {
77         self.lexer.set_in_type(false);
78         (self.lexer, self.context, self.errors, self.sc)
79     }
81     fn lexer(&self) -> &Lexer<'a, S::Token> {
82         &self.lexer
83     }
85     fn lexer_mut(&mut self) -> &mut Lexer<'a, S::Token> {
86         &mut self.lexer
87     }
89     fn continue_from<P: ParserTrait<'a, S, T>>(&mut self, other: P)
90     where
91         T: Clone,
92     {
93         let (mut lexer, context, errors, sc) = other.into_parts();
94         lexer.set_in_type(true);
95         self.lexer = lexer;
96         self.context = context;
97         self.errors = errors;
98         self.sc = sc;
99     }
101     fn add_error(&mut self, error: SyntaxError) {
102         self.errors.push(error)
103     }
105     fn env(&self) -> &ParserEnv {
106         &self.env
107     }
109     fn sc_mut(&mut self) -> &mut S {
110         &mut self.sc
111     }
113     fn drain_skipped_tokens(&mut self) -> std::vec::Drain<S::Token> {
114         self.context.skipped_tokens.drain(..)
115     }
117     fn skipped_tokens(&self) -> &[S::Token] {
118         &self.context.skipped_tokens
119     }
121     fn context_mut(&mut self) -> &mut Context<'a, S::Token> {
122         &mut self.context
123     }
125     fn context(&self) -> &Context<'a, S::Token> {
126         &self.context
127     }
130 impl<'a, S, T: Clone> TypeParser<'a, S, T>
131 where
132     S: SmartConstructors<'a, T>,
133     S::R: NodeType,
135     fn with_expression_parser<F, U>(&mut self, f: F) -> U
136     where
137         F: Fn(&mut ExpressionParser<'a, S, T>) -> U,
138     {
139         let mut lexer = self.lexer.clone();
140         lexer.set_in_type(false);
141         let mut expression_parser: ExpressionParser<S, T> = ExpressionParser::make(
142             lexer,
143             self.env.clone(),
144             self.context.clone(),
145             self.errors.clone(),
146             self.sc.clone(),
147         );
148         let res = f(&mut expression_parser);
149         self.continue_from(expression_parser);
150         res
151     }
153     fn parse_expression(&mut self) -> S::R {
154         self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| p.parse_expression())
155     }
157     fn with_decl_parser<F, U>(&mut self, f: F) -> U
158     where
159         F: Fn(&mut DeclarationParser<'a, S, T>) -> U,
160     {
161         let mut lexer = self.lexer.clone();
162         lexer.set_in_type(false);
164         let mut declaration_parser: DeclarationParser<S, T> = DeclarationParser::make(
165             lexer,
166             self.env.clone(),
167             self.context.clone(),
168             self.errors.clone(),
169             self.sc.clone(),
170         );
171         let res = f(&mut declaration_parser);
172         self.continue_from(declaration_parser);
173         res
174     }
176     // TODO: What about something like for::for? Is that a legal type constant?
177     pub fn parse_type_specifier(&mut self, allow_var: bool, allow_attr: bool) -> S::R {
178         // Strictly speaking, "mixed" is a nullable type specifier. We parse it as
179         // a simple type specifier here.
180         let mut parser1 = self.clone();
181         let token = parser1.next_xhp_class_name_or_other_token();
182         let new_attr_syntax = self.env.allow_new_attribute_syntax;
183         match token.kind() {
184             | TokenKind::Var if allow_var => {
185                 self.continue_from(parser1);
186                 let token = S!(make_token, self, token);
187                 S!(make_simple_type_specifier, self, token)
188             }
189             | TokenKind::This => self.parse_simple_type_or_type_constant(),
190             // Any keyword-type could be a non-keyword type, because PHP, so check whether
191             // these have generics.
192             | TokenKind::Double // TODO: Specification does not mention double; fix it.
193             | TokenKind::Bool
194             | TokenKind::Boolean
195             | TokenKind::Binary
196             | TokenKind::Int
197             | TokenKind::Integer
198             | TokenKind::Float
199             | TokenKind::Real
200             | TokenKind::Num
201             | TokenKind::String
202             | TokenKind::Arraykey
203             | TokenKind::Void
204             | TokenKind::Noreturn
205             | TokenKind::Resource
206             | TokenKind::Object
207             | TokenKind::Mixed
208             | TokenKind::NullLiteral
209             | TokenKind::Name => self.parse_simple_type_or_type_constant_or_generic(),
210             | TokenKind::Namespace => {
211                 let name = self.scan_name_or_qualified_name();
212                 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
213             }
214             | TokenKind::Backslash => {
215                 self.continue_from(parser1);
216                 let missing = S!(make_missing, self, self.pos());
217                 let token = S!(make_token, self, token);
218                 let name = self.scan_qualified_name(missing, token);
219                 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
220             }
221             | TokenKind::SelfToken
222             | TokenKind::Parent => self.parse_simple_type_or_type_constant(),
223             | TokenKind::Category
224             | TokenKind::XHP
225             | TokenKind::XHPClassName => self.parse_simple_type_or_type_constant_or_generic(),
226             | TokenKind::Array => self.parse_array_type_specifier(),
227             | TokenKind::Darray => self.parse_darray_type_specifier(),
228             | TokenKind::Varray => self.parse_varray_type_specifier(),
229             | TokenKind::Vec => self.parse_vec_type_specifier(),
230             | TokenKind::Dict => self.parse_dictionary_type_specifier(),
231             | TokenKind::Keyset => self.parse_keyset_type_specifier(),
232             | TokenKind::Tuple => self.parse_tuple_type_explicit_specifier(),
233             | TokenKind::LeftParen => self.parse_tuple_or_closure_type_specifier(),
234             | TokenKind::Shape => self.parse_shape_specifier(),
235             | TokenKind::Question => self.parse_nullable_type_specifier(),
236             | TokenKind::Tilde => self.parse_like_type_specifier(),
237             | TokenKind::At if !new_attr_syntax => self.parse_soft_type_specifier(),
238             | TokenKind::At if new_attr_syntax => self.parse_attributized_specifier(),
239             | TokenKind::LessThanLessThan if allow_attr => self.parse_attributized_specifier(),
240             | TokenKind::Classname => self.parse_classname_type_specifier(),
241             | _ => {
242                 self.with_error_on_whole_token(Errors::error1007);
243                 let token = self.next_xhp_class_name_or_other_token();
244                 let token = S!(make_token, self, token);
245                 S!(make_error, self, token)
246             }
247         }
248     }
250     // SPEC
251     // type-constant-type-name:
252     //   name  ::  name
253     //   self  ::  name
254     //   this  ::  name
255     //   parent  ::  name
256     //   type-constant-type-name  ::  name
257     fn parse_remaining_type_constant(&mut self, left: S::R) -> S::R {
258         let separator = self.fetch_token();
259         let right = self.next_token_as_name();
260         if right.kind() == TokenKind::Name {
261             let right = S!(make_token, self, right);
262             let syntax = S!(make_type_constant, self, left, separator, right);
263             let token = self.peek_token();
264             if token.kind() == TokenKind::ColonColon {
265                 self.parse_remaining_type_constant(syntax)
266             } else {
267                 syntax
268             }
269         } else {
270             // ERROR RECOVERY: Assume that the thing following the ::
271             // that is not a name belongs to the next thing to be
272             // parsed; treat the name as missing.
273             self.with_error(Errors::error1004);
274             let missing = S!(make_missing, self, self.pos());
275             S!(make_type_constant, self, left, separator, missing)
276         }
277     }
279     //  SPEC
280     // pocket-universe-access:
281     //   name  :@  name
282     //   self  :@  name
283     //   this  :@  name
284     //   parent  :@  name
285     //   pocket-universe-access :@  name
286     fn parse_remaining_pocket_universe_access(&mut self, left: S::R) -> S::R {
287         let separator = self.fetch_token();
288         let right = self.next_token_as_name();
289         if right.kind() == TokenKind::Name {
290             let right = S!(make_token, self, right);
291             let syntax = S!(make_pu_access, self, left, separator, right);
292             let token = self.peek_token();
293             if token.kind() == TokenKind::ColonAt {
294                 self.parse_remaining_pocket_universe_access(syntax)
295             } else {
296                 syntax
297             }
298         } else {
299             // ERROR RECOVERY: Assume that the thing following the :@
300             // that is not a name belongs to the next thing to be
301             // parsed; treat the name as missing.
302             self.with_error(Errors::error1004);
303             let missing = S!(make_missing, self, self.pos());
304             S!(make_pu_access, self, left, separator, missing)
305         }
306     }
308     fn parse_remaining_generic(&mut self, name: S::R) -> S::R {
309         let (arguments, _) = self.parse_generic_type_argument_list();
310         S!(make_generic_type_specifier, self, name, arguments)
311     }
313     pub fn parse_simple_type_or_type_constant(&mut self) -> S::R {
314         let name = self.next_xhp_class_name_or_other();
315         self.parse_remaining_simple_type_or_type_constant(name)
316     }
318     pub fn parse_simple_type_or_generic(&mut self) -> S::R {
319         let name = self.next_xhp_class_name_or_other();
320         self.parse_remaining_simple_type_or_generic(name)
321     }
323     fn parse_remaining_simple_type_or_type_constant(&mut self, name: S::R) -> S::R {
324         let token = self.peek_token();
325         match token.kind() {
326             TokenKind::ColonColon => self.parse_remaining_type_constant(name),
327             TokenKind::ColonAt => self.parse_remaining_pocket_universe_access(name),
328             _ => S!(make_simple_type_specifier, self, name),
329         }
330     }
332     fn parse_simple_type_or_type_constant_or_generic(&mut self) -> S::R {
333         let name = self.next_xhp_class_name_or_other();
334         self.parse_remaining_simple_type_or_type_constant_or_generic(name)
335     }
337     pub fn parse_remaining_type_specifier(&mut self, name: S::R) -> S::R {
338         self.parse_remaining_simple_type_or_type_constant_or_generic(name)
339     }
341     fn parse_remaining_simple_type_or_type_constant_or_generic(&mut self, name: S::R) -> S::R {
342         match self.peek_token_kind_with_possible_attributized_type_list() {
343             TokenKind::LessThan => self.parse_remaining_generic(name),
344             _ => self.parse_remaining_simple_type_or_type_constant(name),
345         }
346     }
348     fn parse_remaining_simple_type_or_generic(&mut self, name: S::R) -> S::R {
349         match self.peek_token_kind_with_possible_attributized_type_list() {
350             TokenKind::LessThan => self.parse_remaining_generic(name),
351             _ => S!(make_simple_type_specifier, self, name),
352         }
353     }
355     // SPEC
356     // generic-type-constraint-list:
357     //   generic-type-constraint
358     //   generic-type-constraint generic-type-constraint-list
359     //
360     // generic-type-constraint:
361     //   as type-specifier
362     //   super type-specifier
363     //
364     // TODO: SPEC ISSUES:
365     // https://github.com/hhvm/hack-langspec/issues/83
366     //
367     // TODO: Do we also need to allow "= type-specifier" here?
368     fn parse_generic_type_constraint_opt(&mut self) -> Option<S::R> {
369         let mut parser1 = self.clone();
370         let token = parser1.next_token();
371         match token.kind() {
372             TokenKind::As | TokenKind::Super => {
373                 self.continue_from(parser1);
374                 let constraint_token = S!(make_token, self, token);
375                 let matched_type = self.parse_type_specifier(false, true);
376                 let type_constraint =
377                     S!(make_type_constraint, self, constraint_token, matched_type);
378                 Some(type_constraint)
379             }
380             _ => None,
381         }
382     }
384     fn parse_variance_opt(&mut self) -> S::R {
385         match self.peek_token_kind() {
386             TokenKind::Plus | TokenKind::Minus => self.fetch_token(),
387             _ => S!(make_missing, self, self.pos()),
388         }
389     }
391     // SPEC
392     // generic-type-parameter:
393     //   generic-type-parameter-reified-opt  generic-type-parameter-variance-opt
394     //     name type-parameter-list? generic-type-constraint-list-opt
395     //
396     // generic-type-parameter-variance:
397     //   +
398     //   -
399     //
400     // TODO: SPEC ISSUE: We allow any number of type constraints, not just zero
401     // or one as indicated in the spec.
402     // https://github.com/hhvm/hack-langspec/issues/83
403     // TODO: Update the spec with reified
404     pub fn parse_type_parameter(&mut self) -> S::R {
405         let attributes = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
406             x.parse_attribute_specification_opt()
407         });
408         let reified = self.optional_token(TokenKind::Reify);
409         let variance = self.parse_variance_opt();
410         let type_name = self.require_name_allow_all_keywords();
411         let param_params = self.parse_generic_type_parameter_list_opt();
412         let constraints =
413             self.parse_list_until_none(|x: &mut Self| x.parse_generic_type_constraint_opt());
414         S!(
415             make_type_parameter,
416             self,
417             attributes,
418             reified,
419             variance,
420             type_name,
421             param_params,
422             constraints
423         )
424     }
426     pub fn parse_generic_type_parameter_list_opt(&mut self) -> S::R {
427         match self.peek_token_kind_with_possible_attributized_type_list() {
428             TokenKind::LessThan => self.parse_generic_type_parameter_list(),
429             _ => S!(make_missing, self, self.pos()),
430         }
431     }
433     // SPEC
434     // type-parameter-list:
435     // < generic-type-parameters  ,-opt >
436     //
437     // generic-type-parameters:
438     //   generic-type-parameter
439     //   generic-type-parameter  ,  generic-type-parameter
440     //
442     pub fn parse_generic_type_parameter_list(&mut self) -> S::R {
443         let left = self.assert_left_angle_in_type_list_with_possible_attribute();
444         let (params, _) = self.parse_comma_list_allow_trailing(
445             TokenKind::GreaterThan,
446             Errors::error1007,
447             |x: &mut Self| x.parse_type_parameter(),
448         );
450         let right = self.require_right_angle();
451         S!(make_type_parameters, self, left, params, right)
452     }
454     fn parse_type_list(&mut self, close_kind: TokenKind) -> S::R {
455         // SPEC:
456         // type-specifier-list:
457         //   type-specifiers  ,opt
458         //
459         // type-specifiers:
460         //   type-specifier
461         //   type-specifiers  ,  type-specifier
462         let (items, _) =
463             self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
464                 x.parse_type_specifier(false, true)
465             });
466         items
467     }
469     // SPEC
470     //
471     // TODO: Add this to the specification.
472     // (This work is tracked by task T22582676.)
473     //
474     // call-convention:
475     //   inout
477     fn parse_call_convention_opt(&mut self) -> S::R {
478         match self.peek_token_kind() {
479             TokenKind::Inout => {
480                 let token = self.next_token();
481                 S!(make_token, self, token)
482             }
483             _ => S!(make_missing, self, self.pos()),
484         }
485     }
487     // SPEC
488     //
489     // TODO: Add this to the specification.
490     // (This work is tracked by task T22582676.)
491     //
492     // closure-param-type-specifier-list:
493     //   closure-param-type-specifiers  ,opt
494     //
495     // closure-param-type-specifiers:
496     //   closure-param-type-specifier
497     //   closure-param-type-specifiers  ,  closure-param-type-specifier
499     fn parse_closure_param_list(&mut self, close_kind: TokenKind) -> S::R {
500         let (items, _) =
501             self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
502                 x.parse_closure_param_type_or_ellipsis()
503             });
504         items
505     }
507     // SPEC
508     //
509     // TODO: Add this to the specification.
510     // (This work is tracked by task T22582676.)
511     //
512     // ERROR RECOVERY: Variadic params cannot be declared inout; this error is
513     // caught in a later pass.
514     //
515     // closure-param-type-specifier:
516     //   call-convention-opt  type-specifier
517     //   type-specifier  ...
518     //   ...
520     fn parse_closure_param_type_or_ellipsis(&mut self) -> S::R {
521         match self.peek_token_kind() {
522             TokenKind::DotDotDot => {
523                 let missing1 = S!(make_missing, self, self.pos());
524                 let missing2 = S!(make_missing, self, self.pos());
525                 let token = self.next_token();
526                 let token = S!(make_token, self, token);
527                 S!(make_variadic_parameter, self, missing1, missing2, token)
528             }
529             _ => {
530                 let callconv = self.parse_call_convention_opt();
531                 let ts = self.parse_type_specifier(false, true);
532                 match self.peek_token_kind() {
533                     TokenKind::DotDotDot => {
534                         let token = self.next_token();
535                         let token = S!(make_token, self, token);
536                         S!(make_variadic_parameter, self, callconv, ts, token)
537                     }
538                     _ => S!(make_closure_parameter_type_specifier, self, callconv, ts),
539                 }
540             }
541         }
542     }
544     fn parse_optionally_reified_type(&mut self) -> S::R {
545         if self.peek_token_kind() == TokenKind::Reify {
546             let token = self.next_token();
547             let reified_kw = S!(make_token, self, token);
548             let type_argument = self.parse_type_specifier(false, true);
549             S!(make_reified_type_argument, self, reified_kw, type_argument)
550         } else {
551             self.parse_type_specifier(false, true)
552         }
553     }
555     pub fn parse_generic_type_argument_list(&mut self) -> (S::R, bool) {
556         // SPEC:
557         // generic-type-argument-list:
558         //   <  generic-type-arguments  ,opt  >
559         //
560         // generic-type-arguments:
561         //   generic-type-argument
562         //   generic-type-arguments  ,  generic-type-argument
563         //
564         // TODO: SPEC ISSUE
565         // https://github.com/hhvm/hack-langspec/issues/84
566         // The specification indicates that "noreturn" is only syntactically valid
567         // as a return type hint, but this is plainly wrong because
568         // Awaitable<noreturn> is a legal type. Likely the correct rule will be to
569         // allow noreturn as a type argument, and then a later semantic analysis
570         // pass can determine when it is being used incorrectly.
571         //
572         // For now, we extend the specification to allow return types, not just
573         // ordinary types.
574         let open_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
575         let (args, no_arg_is_missing) = self.parse_comma_list_allow_trailing(
576             TokenKind::GreaterThan,
577             Errors::error1007,
578             |x: &mut Self| x.parse_optionally_reified_type(),
579         );
580         match self.peek_token_kind() {
581             TokenKind::GreaterThan => {
582                 let close_angle = self.assert_token(TokenKind::GreaterThan);
583                 let result = S!(make_type_arguments, self, open_angle, args, close_angle);
584                 (result, no_arg_is_missing)
585             }
586             _ => {
587                 // ERROR RECOVERY: Don't eat the token that is in the place of the
588                 // missing > or ,.  TokenKind::Assume that it is the > that is missing and
589                 // try to parse whatever is coming after the type.
590                 self.with_error(Errors::error1014);
591                 let missing = S!(make_missing, self, self.pos());
592                 let result = S!(make_type_arguments, self, open_angle, args, missing);
593                 (result, no_arg_is_missing)
594             }
595         }
596     }
598     fn parse_array_type_specifier(&mut self) -> S::R {
599         // We allow
600         // array
601         // array<type>
602         // array<type, type>
603         // TODO: Put a proper reference to the specification in here.
604         // TODO: in HHVM trailing comma is permitted only in the case with one
605         // type argument: array<type, >
606         // so now it is not really comma-separated list
607         let array_token = self.assert_token(TokenKind::Array);
608         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
609             S!(make_simple_type_specifier, self, array_token)
610         } else {
611             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
612             // ERROR RECOVERY: We could improve error recovery by detecting
613             // array<,  and marking the key type as missing.
614             let key_type = self.parse_type_specifier(false, true);
615             let kind = self.peek_token_kind();
616             if kind == TokenKind::GreaterThan {
617                 let right_angle = self.fetch_token();
618                 S!(
619                     make_vector_array_type_specifier,
620                     self,
621                     array_token,
622                     left_angle,
623                     key_type,
624                     right_angle
625                 )
626             } else if kind == TokenKind::Comma {
627                 let comma = self.fetch_token();
628                 let next_token_kind = self.peek_token_kind();
629                 let value_type = if next_token_kind == TokenKind::GreaterThan {
630                     S!(make_missing, self, self.pos())
631                 } else {
632                     self.parse_type_specifier(false, true)
633                 };
634                 let right_angle = self.require_right_angle();
635                 S!(
636                     make_map_array_type_specifier,
637                     self,
638                     array_token,
639                     left_angle,
640                     key_type,
641                     comma,
642                     value_type,
643                     right_angle,
644                 )
645             } else {
646                 // ERROR RECOVERY: TokenKind::Assume that the > is missing and keep going.
647                 let right_angle = S!(make_missing, self, self.pos());
648                 S!(
649                     make_vector_array_type_specifier,
650                     self,
651                     array_token,
652                     left_angle,
653                     key_type,
654                     right_angle
655                 )
656             }
657         }
658     }
660     fn parse_darray_type_specifier(&mut self) -> S::R {
661         // darray<type, type>
662         let array_token = self.assert_token(TokenKind::Darray);
663         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
664             S!(make_simple_type_specifier, self, array_token)
665         } else {
666             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
667             let key_type = self.parse_type_specifier(false, true);
668             let comma = self.require_comma();
669             let value_type = self.parse_type_specifier(false, true);
670             let optional_comma = self.optional_token(TokenKind::Comma);
671             let right_angle = self.require_right_angle();
672             S!(
673                 make_darray_type_specifier,
674                 self,
675                 array_token,
676                 left_angle,
677                 key_type,
678                 comma,
679                 value_type,
680                 optional_comma,
681                 right_angle,
682             )
683         }
684     }
686     fn parse_varray_type_specifier(&mut self) -> S::R {
687         // varray<type>
688         let array_token = self.assert_token(TokenKind::Varray);
689         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
690             S!(make_simple_type_specifier, self, array_token)
691         } else {
692             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
693             let value_type = self.parse_type_specifier(false, true);
694             let optional_comma = self.optional_token(TokenKind::Comma);
695             let right_angle = self.require_right_angle();
696             S!(
697                 make_varray_type_specifier,
698                 self,
699                 array_token,
700                 left_angle,
701                 value_type,
702                 optional_comma,
703                 right_angle,
704             )
705         }
706     }
708     fn parse_vec_type_specifier(&mut self) -> S::R {
709         // vec < type-specifier >
710         // TODO: Should we allow a trailing comma?
711         // TODO: Add this to the specification
712         // ERROR RECOVERY: If there is no type argument list then just make
713         // this a simple type.  TODO: Should this be an error at parse time? what
714         // about at type checking time?
715         let keyword = self.assert_token(TokenKind::Vec);
716         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
717             S!(make_simple_type_specifier, self, keyword)
718         } else {
719             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
720             let t = self.parse_type_specifier(false, true);
721             let optional_comma = self.optional_token(TokenKind::Comma);
722             let right = self.require_right_angle();
723             S!(
724                 make_vector_type_specifier,
725                 self,
726                 keyword,
727                 left,
728                 t,
729                 optional_comma,
730                 right
731             )
732         }
733     }
735     fn parse_keyset_type_specifier(&mut self) -> S::R {
736         // keyset < type-specifier >
737         // TODO: Should we allow a trailing comma?
738         // TODO: Add this to the specification
739         // ERROR RECOVERY: If there is no type argument list then just make
740         // this a simple type.  TODO: Should this be an error at parse time? what
741         // about at type checking time?
742         let keyword = self.assert_token(TokenKind::Keyset);
743         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
744             S!(make_simple_type_specifier, self, keyword)
745         } else {
746             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
747             let t = self.parse_type_specifier(false, true);
748             let comma = self.optional_token(TokenKind::Comma);
749             let right = self.require_right_angle();
750             S!(
751                 make_keyset_type_specifier,
752                 self,
753                 keyword,
754                 left,
755                 t,
756                 comma,
757                 right
758             )
759         }
760     }
762     fn parse_tuple_type_explicit_specifier(&mut self) -> S::R {
763         // tuple < type-specifier-list >
764         // TODO: Add this to the specification
765         let keyword = self.assert_token(TokenKind::Tuple);
766         let left_angle = if self.peek_next_partial_token_is_triple_left_angle() {
767             self.assert_left_angle_in_type_list_with_possible_attribute()
768         } else {
769             self.require_left_angle()
770         };
771         let args = self.parse_type_list(TokenKind::GreaterThan);
772         let mut parser1 = self.clone();
773         let right_angle = parser1.next_token();
774         if right_angle.kind() == TokenKind::GreaterThan {
775             self.continue_from(parser1);
776             let token = S!(make_token, self, right_angle);
777             S!(
778                 make_tuple_type_explicit_specifier,
779                 self,
780                 keyword,
781                 left_angle,
782                 args,
783                 token
784             )
785         } else {
786             // ERROR RECOVERY: Don't eat the token that is in the place of the
787             // missing > or ,.  TokenKind::Assume that it is the > that is missing and
788             // try to parse whatever is coming after the type.
789             self.with_error(Errors::error1022);
790             let right_angle = S!(make_missing, self, self.pos());
791             S!(
792                 make_tuple_type_explicit_specifier,
793                 self,
794                 keyword,
795                 left_angle,
796                 args,
797                 right_angle
798             )
799         }
800     }
802     fn parse_dictionary_type_specifier(&mut self) -> S::R {
803         // dict < type-specifier , type-specifier >
804         //
805         // TODO: Add this to the specification
806         //
807         // Though we require there to be exactly two items, we actually parse
808         // an arbitrary comma-separated list here.
809         //
810         // TODO: Give an error in a later pass if there are not exactly two members.
811         //
812         // ERROR RECOVERY: If there is no type argument list then just make this
813         // a simple type.  TODO: Should this be an error at parse time?  what
814         // about at type checking time?
815         let keyword = self.assert_token(TokenKind::Dict);
816         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
817             S!(make_simple_type_specifier, self, keyword)
818         } else {
819             // TODO: This allows "noreturn" as a type argument. Should we
820             // disallow that at parse time?
821             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
822             let (arguments, _) = self.parse_comma_list_allow_trailing(
823                 TokenKind::GreaterThan,
824                 Errors::error1007,
825                 |x: &mut Self| x.parse_return_type(),
826             );
827             let right = self.require_right_angle();
828             S!(
829                 make_dictionary_type_specifier,
830                 self,
831                 keyword,
832                 left,
833                 arguments,
834                 right
835             )
836         }
837     }
839     fn parse_tuple_or_closure_type_specifier(&mut self) -> S::R {
840         let mut parser1 = self.clone();
841         let _ = parser1.assert_token(TokenKind::LeftParen);
842         let token = parser1.peek_token();
843         match token.kind() {
844             TokenKind::Function | TokenKind::Coroutine => self.parse_closure_type_specifier(),
845             _ => self.parse_tuple_or_union_or_intersection_type_specifier(),
846         }
847     }
849     fn parse_closure_type_specifier(&mut self) -> S::R {
850         // SPEC
851         //
852         // TODO: Update the specification with closure-param-type-specifier-list-opt.
853         // (This work is tracked by task T22582676.)
854         //
855         // TODO: Update grammar for inout parameters.
856         // (This work is tracked by task T22582715.)
857         //
858         // closure-type-specifier:
859         //   ( function ( \
860         //   closure-param-type-specifier-list-opt \
861         //   ) : type-specifier )
862         //
863         // TODO: Error recovery is pretty weak here. We could be smarter.
864         let olp = self.fetch_token();
865         let fnc = self.fetch_token();
866         let ilp = self.require_left_paren();
867         let (pts, irp) = if self.peek_token_kind() == TokenKind::RightParen {
868             let missing = S!(make_missing, self, self.pos());
869             let token = self.next_token();
870             let token = S!(make_token, self, token);
871             (missing, token)
872         } else {
873             // TODO add second pass checking to ensure ellipsis is the last arg
874             let pts = self.parse_closure_param_list(TokenKind::RightParen);
875             let irp = self.require_right_paren();
876             (pts, irp)
877         };
878         let col = self.require_colon();
879         let ret = self.parse_type_specifier(false, true);
880         let orp = self.require_right_paren();
881         S!(
882             make_closure_type_specifier,
883             self,
884             olp,
885             fnc,
886             ilp,
887             pts,
888             irp,
889             col,
890             ret,
891             orp
892         )
893     }
895     fn parse_tuple_or_union_or_intersection_type_specifier(&mut self) -> S::R {
896         // SPEC
897         // tuple-union-intersection-type-specifier:
898         //   ( type-specifier  ,  type-specifier-list  )
899         //   ( type-specifier  &  intersection-type-specifier-list )
900         //   ( type-specifier  |  union-type-specifier-list )
901         // type-specifier-list:
902         //   type-specifiers  ,opt
903         //   type-specifiers
904         //   type-specifier
905         //   type-specifiers , type-specifier
906         // intersection-type-specifier-list:
907         //   type-specifier
908         //   intersection-type-specifier-list & type-specifier
909         // union-type-specifier-list:
910         //   type-specifier
911         //   union-type-specifier-list | type-specifier
913         // TODO: Here we parse a type list with one or more items, but the grammar
914         // actually requires a type list with two or more items. Give an error in
915         // a later pass if there is only one item here.
917         let left_paren = self.assert_token(TokenKind::LeftParen);
919         let (args, _, separator_kind) = self.parse_separated_list_predicate(
920             |x| x == TokenKind::Bar || x == TokenKind::Ampersand || x == TokenKind::Comma,
921             SeparatedListKind::TrailingAllowed,
922             |x| x == TokenKind::RightParen,
923             Errors::error1007,
924             |x: &mut Self| x.parse_type_specifier(false, true),
925         );
927         if self.peek_token_kind() == TokenKind::RightParen {
928             let right_paren = self.next_token();
929             let token = S!(make_token, self, right_paren);
930             match separator_kind {
931                 TokenKind::Bar => S!(make_union_type_specifier, self, left_paren, args, token),
932                 TokenKind::Ampersand => S!(
933                     make_intersection_type_specifier,
934                     self,
935                     left_paren,
936                     args,
937                     token
938                 ),
939                 _ => S!(make_tuple_type_specifier, self, left_paren, args, token),
940             }
941         } else {
942             // ERROR RECOVERY: Don't eat the token that is in the place of the
943             // missing ) or ,.  Assume that it is the ) that is missing and
944             // try to parse whatever is coming after the type.
945             self.with_error(Errors::error1022);
946             let missing = S!(make_missing, self, self.pos());
947             S!(make_tuple_type_specifier, self, left_paren, args, missing)
948         }
949     }
951     fn parse_nullable_type_specifier(&mut self) -> S::R {
952         // SPEC:
953         // nullable-type-specifier:
954         //   ? type-specifier
955         //   mixed
956         //
957         // Note that we parse "mixed" as a simple type specifier, even though
958         // technically it is classified as a nullable type specifier by the grammar.
959         // Note that it is perfectly legal to have trivia between the ? and the
960         // underlying type.
961         let question = self.assert_token(TokenKind::Question);
962         let nullable_type = self.parse_type_specifier(false, true);
963         S!(make_nullable_type_specifier, self, question, nullable_type)
964     }
966     fn parse_like_type_specifier(&mut self) -> S::R {
967         // SPEC:
968         // like-type-specifier:
969         //   ~ type-specifier
970         //
971         // Note that it is perfectly legal to have trivia between the ~ and the
972         // underlying type.
973         let tilde = self.assert_token(TokenKind::Tilde);
974         let like_type = self.parse_type_specifier(false, true);
975         S!(make_like_type_specifier, self, tilde, like_type)
976     }
978     fn parse_soft_type_specifier(&mut self) -> S::R {
979         // SPEC (Draft)
980         // soft-type-specifier:
981         //   @ type-specifier
982         //
983         // TODO: The spec does not mention this type grammar.  Work out where and
984         // when it is legal, and what the exact semantics are, and put it in the spec.
985         // Add an error pass if necessary to identify illegal usages of this type.
986         //
987         // Note that it is legal for trivia to come between the @ and the type.
988         let soft_at = self.assert_token(TokenKind::At);
989         let soft_type = self.parse_type_specifier(false, true);
990         S!(make_soft_type_specifier, self, soft_at, soft_type)
991     }
993     fn parse_attributized_specifier(&mut self) -> S::R {
994         // SPEC
995         // attributized-specifier:
996         // attribute-specification-opt type-specifier
997         let attribute_spec_opt = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
998             x.parse_attribute_specification_opt()
999         });
1000         let attributized_type = self.parse_type_specifier(false, true);
1001         S!(
1002             make_attributized_specifier,
1003             self,
1004             attribute_spec_opt,
1005             attributized_type
1006         )
1007     }
1009     fn parse_classname_type_specifier(&mut self) -> S::R {
1010         // SPEC
1011         // classname-type-specifier:
1012         //   classname
1013         //   classname  <  qualified-name generic-type-argument-list-opt >
1014         //
1015         // TODO: We parse any type as the class name type; we should write an
1016         // error detection pass later that determines when this is a bad type.
1017         //
1018         // TODO: Is this grammar correct?  In particular, can the name have a
1019         // scope resolution operator (::) in it?  Find out and update the spec if
1020         // this is permitted.
1022         // TODO ERROR RECOVERY is unsophisticated here.
1023         let classname = self.fetch_token();
1024         match self.peek_token_kind() {
1025             TokenKind::LessThan => {
1026                 let left_angle = self.require_left_angle();
1027                 let classname_type = self.parse_type_specifier(false, true);
1028                 let optional_comma = self.optional_token(TokenKind::Comma);
1029                 let right_angle = self.require_right_angle();
1030                 S!(
1031                     make_classname_type_specifier,
1032                     self,
1033                     classname,
1034                     left_angle,
1035                     classname_type,
1036                     optional_comma,
1037                     right_angle,
1038                 )
1039             }
1040             _ => {
1041                 let missing1 = S!(make_missing, self, self.pos());
1042                 let missing2 = S!(make_missing, self, self.pos());
1043                 let missing3 = S!(make_missing, self, self.pos());
1044                 let missing4 = S!(make_missing, self, self.pos());
1045                 S!(
1046                     make_classname_type_specifier,
1047                     self,
1048                     classname,
1049                     missing1,
1050                     missing2,
1051                     missing3,
1052                     missing4
1053                 )
1054             }
1055         }
1056     }
1058     fn parse_field_specifier(&mut self) -> S::R {
1059         // SPEC
1060         // field-specifier:
1061         //   ?-opt present-field-specifier
1062         // present-field-specifier:
1063         //   single-quoted-string-literal  =>  type-specifier
1064         //   qualified-name  =>  type-specifier
1065         //   scope-resolution-expression  =>  type-specifier
1067         // TODO: We require that it be either all literals or no literals in the
1068         // set of specifiers; make an error reporting pass that detects this.
1070         // ERROR RECOVERY: We allow any expression for the left-hand side.
1071         // TODO: Make an error-detecting pass that gives an error if the left-hand
1072         // side is not a literal or name.
1073         let question = if self.peek_token_kind() == TokenKind::Question {
1074             self.assert_token(TokenKind::Question)
1075         } else {
1076             S!(make_missing, self, self.pos())
1077         };
1078         let name = self.parse_expression();
1079         let arrow = self.require_arrow();
1080         let field_type = self.parse_type_specifier(false, true);
1081         S!(
1082             make_field_specifier,
1083             self,
1084             question,
1085             name,
1086             arrow,
1087             field_type
1088         )
1089     }
1091     fn parse_shape_specifier(&mut self) -> S::R {
1092         // SPEC
1093         // shape-specifier:
1094         //   shape ( field-specifier-list-opt )
1095         // field-specifier-list:
1096         //   field-specifiers  ,  ...
1097         //   field-specifiers  ,-opt
1098         // field-specifiers:
1099         //   field-specifier
1100         //   field-specifiers  ,  field-specifier
1101         //
1102         // TODO: ERROR RECOVERY is not very sophisticated here.
1103         let shape = self.fetch_token();
1104         let lparen = self.require_left_paren();
1105         let is_closing_token =
1106             |x: TokenKind| x == TokenKind::RightParen || x == TokenKind::DotDotDot;
1107         let fields = self.parse_comma_list_opt_allow_trailing_predicate(
1108             &is_closing_token,
1109             Errors::error1025,
1110             |x: &mut Self| x.parse_field_specifier(),
1111         );
1112         let ellipsis = if self.peek_token_kind() == TokenKind::DotDotDot {
1113             self.assert_token(TokenKind::DotDotDot)
1114         } else {
1115             S!(make_missing, self, self.pos())
1116         };
1117         let rparen = self.require_right_paren();
1118         S!(
1119             make_shape_type_specifier,
1120             self,
1121             shape,
1122             lparen,
1123             fields,
1124             ellipsis,
1125             rparen
1126         )
1127     }
1129     pub fn parse_type_constraint_opt(&mut self) -> S::R {
1130         // SPEC
1131         // type-constraint:
1132         //   as  type-specifier
1133         // TODO: Is this correct? Or do we need to allow "super" as well?
1134         // TODO: What about = ?
1135         if self.peek_token_kind() == TokenKind::As {
1136             let constraint_as = self.next_token();
1137             let constraint_as = S!(make_token, self, constraint_as);
1138             let constraint_type = self.parse_type_specifier(false, true);
1139             S!(make_type_constraint, self, constraint_as, constraint_type)
1140         } else {
1141             S!(make_missing, self, self.pos())
1142         }
1143     }
1145     pub fn parse_return_type(&mut self) -> S::R {
1146         if self.peek_token_kind() == TokenKind::Noreturn {
1147             let token = self.next_token();
1148             S!(make_token, self, token)
1149         } else {
1150             self.parse_type_specifier(false, true)
1151         }
1152     }