1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
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::smart_constructors::{NodeType, SmartConstructors};
14 use parser_core_types::lexable_token::LexableToken;
15 use parser_core_types::syntax_error::{self as Errors, SyntaxError};
16 use parser_core_types::token_kind::TokenKind;
18 pub struct TypeParser<'a, S, T>
20 S: SmartConstructors<'a, T>,
23 lexer: Lexer<'a, S::Token>,
25 context: Context<'a, S::Token>,
26 errors: Vec<SyntaxError>,
30 impl<'a, S, T: Clone> std::clone::Clone for TypeParser<'a, S, T>
32 S: SmartConstructors<'a, T>,
35 fn clone(&self) -> Self {
37 lexer: self.lexer.clone(),
38 env: self.env.clone(),
39 context: self.context.clone(),
40 errors: self.errors.clone(),
46 impl<'a, S, T: Clone> ParserTrait<'a, S, T> for TypeParser<'a, S, T>
48 S: SmartConstructors<'a, T>,
52 mut lexer: Lexer<'a, S::Token>,
54 context: Context<'a, S::Token>,
55 errors: Vec<SyntaxError>,
58 lexer.set_in_type(true);
72 Context<'a, S::Token>,
76 self.lexer.set_in_type(false);
77 (self.lexer, self.context, self.errors, self.sc)
80 fn lexer(&self) -> &Lexer<'a, S::Token> {
84 fn lexer_mut(&mut self) -> &mut Lexer<'a, S::Token> {
88 fn continue_from<P: ParserTrait<'a, S, T>>(&mut self, other: P)
92 let (mut lexer, context, errors, sc) = other.into_parts();
93 lexer.set_in_type(true);
95 self.context = context;
100 fn add_error(&mut self, error: SyntaxError) {
101 self.errors.push(error)
104 fn env(&self) -> &ParserEnv {
108 fn sc_mut(&mut self) -> &mut S {
112 fn skipped_tokens_mut(&mut self) -> &mut Vec<S::Token> {
113 &mut self.context.skipped_tokens
116 fn skipped_tokens(&self) -> &[S::Token] {
117 &self.context.skipped_tokens
120 fn context_mut(&mut self) -> &mut Context<'a, S::Token> {
124 fn context(&self) -> &Context<'a, S::Token> {
129 impl<'a, S, T: Clone> TypeParser<'a, S, T>
131 S: SmartConstructors<'a, T>,
134 fn with_expression_parser<F, U>(&mut self, f: F) -> U
136 F: Fn(&mut ExpressionParser<'a, S, T>) -> U,
138 let mut lexer = self.lexer.clone();
139 lexer.set_in_type(false);
140 let mut expression_parser: ExpressionParser<S, T> = ExpressionParser::make(
143 self.context.clone(),
147 let res = f(&mut expression_parser);
148 self.continue_from(expression_parser);
152 fn parse_expression(&mut self) -> S::R {
153 self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| p.parse_expression())
156 fn with_decl_parser<F, U>(&mut self, f: F) -> U
158 F: Fn(&mut DeclarationParser<'a, S, T>) -> U,
160 let mut lexer = self.lexer.clone();
161 lexer.set_in_type(false);
163 let mut declaration_parser: DeclarationParser<S, T> = DeclarationParser::make(
166 self.context.clone(),
170 let res = f(&mut declaration_parser);
171 self.continue_from(declaration_parser);
175 // TODO: What about something like for::for? Is that a legal type constant?
176 pub fn parse_type_specifier(&mut self, allow_var: bool, allow_attr: bool) -> S::R {
177 // Strictly speaking, "mixed" is a nullable type specifier. We parse it as
178 // a simple type specifier here.
179 let mut parser1 = self.clone();
180 let token = parser1.next_xhp_class_name_or_other_token();
181 let new_attr_syntax = self.env.allow_new_attribute_syntax;
183 | TokenKind::Var if allow_var => {
184 self.continue_from(parser1);
185 let token = S!(make_token, self, token);
186 S!(make_simple_type_specifier, self, token)
188 | TokenKind::This => self.parse_simple_type_or_type_constant(),
189 // Any keyword-type could be a non-keyword type, because PHP, so check whether
190 // these have generics.
191 | TokenKind::Double // TODO: Specification does not mention double; fix it.
201 | TokenKind::Arraykey
203 | TokenKind::Noreturn
204 | TokenKind::Resource
207 | TokenKind::NullLiteral
208 | TokenKind::Name => self.parse_simple_type_or_type_constant_or_generic(),
209 | TokenKind::Namespace => {
210 let name = self.scan_name_or_qualified_name();
211 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
213 | TokenKind::Backslash => {
214 self.continue_from(parser1);
215 let missing = S!(make_missing, self, self.pos());
216 let token = S!(make_token, self, token);
217 let name = self.scan_qualified_name(missing, token);
218 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
220 | TokenKind::SelfToken
221 | TokenKind::Parent => self.parse_simple_type_or_type_constant(),
222 | TokenKind::Category
223 | TokenKind::XHPClassName => self.parse_simple_type_or_type_constant_or_generic(),
224 | TokenKind::Array => self.parse_array_type_specifier(),
225 | TokenKind::Darray => self.parse_darray_type_specifier(),
226 | TokenKind::Varray => self.parse_varray_type_specifier(),
227 | TokenKind::Vec => self.parse_vec_type_specifier(),
228 | TokenKind::Dict => self.parse_dictionary_type_specifier(),
229 | TokenKind::Keyset => self.parse_keyset_type_specifier(),
230 | TokenKind::Tuple => self.parse_tuple_type_explicit_specifier(),
231 | TokenKind::LeftParen => self.parse_tuple_or_closure_type_specifier(),
232 | TokenKind::Shape => self.parse_shape_specifier(),
233 | TokenKind::Question => self.parse_nullable_type_specifier(),
234 | TokenKind::Tilde => self.parse_like_type_specifier(),
235 | TokenKind::At if !new_attr_syntax => self.parse_soft_type_specifier(),
236 | TokenKind::At if new_attr_syntax => self.parse_attributized_specifier(),
237 | TokenKind::LessThanLessThan if allow_attr => self.parse_attributized_specifier(),
238 | TokenKind::Classname => self.parse_classname_type_specifier(),
240 self.with_error_on_whole_token(Errors::error1007);
241 let token = self.next_xhp_class_name_or_other_token();
242 let token = S!(make_token, self, token);
243 S!(make_error, self, token)
249 // type-constant-type-name:
254 // type-constant-type-name :: name
255 fn parse_remaining_type_constant(&mut self, left: S::R) -> S::R {
256 let separator = self.fetch_token();
257 let right = self.next_token_as_name();
258 if right.kind() == TokenKind::Name {
259 let right = S!(make_token, self, right);
260 let syntax = S!(make_type_constant, self, left, separator, right);
261 let token = self.peek_token();
262 if token.kind() == TokenKind::ColonColon {
263 self.parse_remaining_type_constant(syntax)
268 // ERROR RECOVERY: Assume that the thing following the ::
269 // that is not a name belongs to the next thing to be
270 // parsed; treat the name as missing.
271 self.with_error(Errors::error1004);
272 let missing = S!(make_missing, self, self.pos());
273 S!(make_type_constant, self, left, separator, missing)
278 // pocket-universe-access:
283 // pocket-universe-access :@ name
284 fn parse_remaining_pocket_universe_access(&mut self, left: S::R) -> S::R {
285 let separator = self.fetch_token();
286 let right = self.next_token_as_name();
287 if right.kind() == TokenKind::Name {
288 let right = S!(make_token, self, right);
289 let syntax = S!(make_pu_access, self, left, separator, right);
290 let token = self.peek_token();
291 if token.kind() == TokenKind::ColonAt {
292 self.parse_remaining_pocket_universe_access(syntax)
297 // ERROR RECOVERY: Assume that the thing following the :@
298 // that is not a name belongs to the next thing to be
299 // parsed; treat the name as missing.
300 self.with_error(Errors::error1004);
301 let missing = S!(make_missing, self, self.pos());
302 S!(make_pu_access, self, left, separator, missing)
306 fn parse_remaining_generic(&mut self, name: S::R) -> S::R {
307 let (arguments, _) = self.parse_generic_type_argument_list();
308 S!(make_generic_type_specifier, self, name, arguments)
311 pub fn parse_simple_type_or_type_constant(&mut self) -> S::R {
312 let name = self.next_xhp_class_name_or_other();
313 self.parse_remaining_simple_type_or_type_constant(name)
316 pub fn parse_simple_type_or_generic(&mut self) -> S::R {
317 let name = self.next_xhp_class_name_or_other();
318 self.parse_remaining_simple_type_or_generic(name)
321 fn parse_remaining_simple_type_or_type_constant(&mut self, name: S::R) -> S::R {
322 let token = self.peek_token();
324 TokenKind::ColonColon => self.parse_remaining_type_constant(name),
325 TokenKind::ColonAt => self.parse_remaining_pocket_universe_access(name),
326 _ => S!(make_simple_type_specifier, self, name),
330 fn parse_simple_type_or_type_constant_or_generic(&mut self) -> S::R {
331 let name = self.next_xhp_class_name_or_other();
332 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
335 pub fn parse_remaining_type_specifier(&mut self, name: S::R) -> S::R {
336 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
339 fn parse_remaining_simple_type_or_type_constant_or_generic(&mut self, name: S::R) -> S::R {
340 match self.peek_token_kind_with_possible_attributized_type_list() {
341 TokenKind::LessThan => self.parse_remaining_generic(name),
342 _ => self.parse_remaining_simple_type_or_type_constant(name),
346 fn parse_remaining_simple_type_or_generic(&mut self, name: S::R) -> S::R {
347 match self.peek_token_kind_with_possible_attributized_type_list() {
348 TokenKind::LessThan => self.parse_remaining_generic(name),
349 _ => S!(make_simple_type_specifier, self, name),
354 // generic-type-constraint-list:
355 // generic-type-constraint
356 // generic-type-constraint generic-type-constraint-list
358 // generic-type-constraint:
360 // super type-specifier
362 // TODO: SPEC ISSUES:
363 // https://github.com/hhvm/hack-langspec/issues/83
365 // TODO: Do we also need to allow "= type-specifier" here?
366 fn parse_generic_type_constraint_opt(&mut self) -> Option<S::R> {
367 let mut parser1 = self.clone();
368 let token = parser1.next_token();
370 TokenKind::As | TokenKind::Super => {
371 self.continue_from(parser1);
372 let constraint_token = S!(make_token, self, token);
373 let matched_type = self.parse_type_specifier(false, true);
374 let type_constraint =
375 S!(make_type_constraint, self, constraint_token, matched_type);
376 Some(type_constraint)
382 fn parse_variance_opt(&mut self) -> S::R {
383 match self.peek_token_kind() {
384 TokenKind::Plus | TokenKind::Minus => self.fetch_token(),
385 _ => S!(make_missing, self, self.pos()),
390 // generic-type-parameter:
391 // generic-type-parameter-reified-opt generic-type-parameter-variance-opt
392 // name generic-type-constraint-list-opt
394 // generic-type-parameter-variance:
398 // TODO: SPEC ISSUE: We allow any number of type constraints, not just zero
399 // or one as indicated in the spec.
400 // https://github.com/hhvm/hack-langspec/issues/83
401 // TODO: Update the spec with reified
402 fn parse_type_parameter(&mut self) -> S::R {
403 let attributes = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
404 x.parse_attribute_specification_opt()
406 let reified = self.optional_token(TokenKind::Reify);
407 let variance = self.parse_variance_opt();
408 let type_name = self.require_name_allow_all_keywords();
410 self.parse_list_until_none(|x: &mut Self| x.parse_generic_type_constraint_opt());
423 // type-parameter-list:
424 // < generic-type-parameters ,-opt >
426 // generic-type-parameters:
427 // generic-type-parameter
428 // generic-type-parameter , generic-type-parameter
431 pub fn parse_generic_type_parameter_list(&mut self) -> S::R {
432 let left = self.assert_left_angle_in_type_list_with_possible_attribute();
433 let (params, _) = self.parse_comma_list_allow_trailing(
434 TokenKind::GreaterThan,
436 |x: &mut Self| x.parse_type_parameter(),
439 let right = self.require_right_angle();
440 S!(make_type_parameters, self, left, params, right)
443 fn parse_type_list(&mut self, close_kind: TokenKind) -> S::R {
445 // type-specifier-list:
446 // type-specifiers ,opt
450 // type-specifiers , type-specifier
452 self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
453 x.parse_type_specifier(false, true)
460 // TODO: Add this to the specification.
461 // (This work is tracked by task T22582676.)
466 fn parse_call_convention_opt(&mut self) -> S::R {
467 match self.peek_token_kind() {
468 TokenKind::Inout => {
469 let token = self.next_token();
470 S!(make_token, self, token)
472 _ => S!(make_missing, self, self.pos()),
478 // TODO: Add this to the specification.
479 // (This work is tracked by task T22582676.)
481 // closure-param-type-specifier-list:
482 // closure-param-type-specifiers ,opt
484 // closure-param-type-specifiers:
485 // closure-param-type-specifier
486 // closure-param-type-specifiers , closure-param-type-specifier
488 fn parse_closure_param_list(&mut self, close_kind: TokenKind) -> S::R {
490 self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
491 x.parse_closure_param_type_or_ellipsis()
498 // TODO: Add this to the specification.
499 // (This work is tracked by task T22582676.)
501 // ERROR RECOVERY: Variadic params cannot be declared inout; this error is
502 // caught in a later pass.
504 // closure-param-type-specifier:
505 // call-convention-opt type-specifier
506 // type-specifier ...
509 fn parse_closure_param_type_or_ellipsis(&mut self) -> S::R {
510 match self.peek_token_kind() {
511 TokenKind::DotDotDot => {
512 let missing1 = S!(make_missing, self, self.pos());
513 let missing2 = S!(make_missing, self, self.pos());
514 let token = self.next_token();
515 let token = S!(make_token, self, token);
516 S!(make_variadic_parameter, self, missing1, missing2, token)
519 let callconv = self.parse_call_convention_opt();
520 let ts = self.parse_type_specifier(false, true);
521 match self.peek_token_kind() {
522 TokenKind::DotDotDot => {
523 let token = self.next_token();
524 let token = S!(make_token, self, token);
525 S!(make_variadic_parameter, self, callconv, ts, token)
527 _ => S!(make_closure_parameter_type_specifier, self, callconv, ts),
533 fn parse_optionally_reified_type(&mut self) -> S::R {
534 if self.peek_token_kind() == TokenKind::Reify {
535 let token = self.next_token();
536 let reified_kw = S!(make_token, self, token);
537 let type_argument = self.parse_type_specifier(false, true);
538 S!(make_reified_type_argument, self, reified_kw, type_argument)
540 self.parse_type_specifier(false, true)
544 pub fn parse_generic_type_argument_list(&mut self) -> (S::R, bool) {
546 // generic-type-argument-list:
547 // < generic-type-arguments ,opt >
549 // generic-type-arguments:
550 // generic-type-argument
551 // generic-type-arguments , generic-type-argument
554 // https://github.com/hhvm/hack-langspec/issues/84
555 // The specification indicates that "noreturn" is only syntactically valid
556 // as a return type hint, but this is plainly wrong because
557 // Awaitable<noreturn> is a legal type. Likely the correct rule will be to
558 // allow noreturn as a type argument, and then a later semantic analysis
559 // pass can determine when it is being used incorrectly.
561 // For now, we extend the specification to allow return types, not just
563 let open_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
564 let (args, no_arg_is_missing) = self.parse_comma_list_allow_trailing(
565 TokenKind::GreaterThan,
567 |x: &mut Self| x.parse_optionally_reified_type(),
569 match self.peek_token_kind() {
570 TokenKind::GreaterThan => {
571 let close_angle = self.assert_token(TokenKind::GreaterThan);
572 let result = S!(make_type_arguments, self, open_angle, args, close_angle);
573 (result, no_arg_is_missing)
576 // ERROR RECOVERY: Don't eat the token that is in the place of the
577 // missing > or ,. TokenKind::Assume that it is the > that is missing and
578 // try to parse whatever is coming after the type.
579 self.with_error(Errors::error1014);
580 let missing = S!(make_missing, self, self.pos());
581 let result = S!(make_type_arguments, self, open_angle, args, missing);
582 (result, no_arg_is_missing)
587 fn parse_array_type_specifier(&mut self) -> S::R {
592 // TODO: Put a proper reference to the specification in here.
593 // TODO: in HHVM trailing comma is permitted only in the case with one
594 // type argument: array<type, >
595 // so now it is not really comma-separated list
596 let array_token = self.assert_token(TokenKind::Array);
597 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
598 S!(make_simple_type_specifier, self, array_token)
600 let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
601 // ERROR RECOVERY: We could improve error recovery by detecting
602 // array<, and marking the key type as missing.
603 let key_type = self.parse_type_specifier(false, true);
604 let kind = self.peek_token_kind();
605 if kind == TokenKind::GreaterThan {
606 let right_angle = self.fetch_token();
608 make_vector_array_type_specifier,
615 } else if kind == TokenKind::Comma {
616 let comma = self.fetch_token();
617 let next_token_kind = self.peek_token_kind();
618 let value_type = if next_token_kind == TokenKind::GreaterThan {
619 S!(make_missing, self, self.pos())
621 self.parse_type_specifier(false, true)
623 let right_angle = self.require_right_angle();
625 make_map_array_type_specifier,
635 // ERROR RECOVERY: TokenKind::Assume that the > is missing and keep going.
636 let right_angle = S!(make_missing, self, self.pos());
638 make_vector_array_type_specifier,
649 fn parse_darray_type_specifier(&mut self) -> S::R {
650 // darray<type, type>
651 let array_token = self.assert_token(TokenKind::Darray);
652 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
653 S!(make_simple_type_specifier, self, array_token)
655 let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
656 let key_type = self.parse_type_specifier(false, true);
657 let comma = self.require_comma();
658 let value_type = self.parse_type_specifier(false, true);
659 let optional_comma = self.optional_token(TokenKind::Comma);
660 let right_angle = self.require_right_angle();
662 make_darray_type_specifier,
675 fn parse_varray_type_specifier(&mut self) -> S::R {
677 let array_token = self.assert_token(TokenKind::Varray);
678 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
679 S!(make_simple_type_specifier, self, array_token)
681 let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
682 let value_type = self.parse_type_specifier(false, true);
683 let optional_comma = self.optional_token(TokenKind::Comma);
684 let right_angle = self.require_right_angle();
686 make_varray_type_specifier,
697 fn parse_vec_type_specifier(&mut self) -> S::R {
698 // vec < type-specifier >
699 // TODO: Should we allow a trailing comma?
700 // TODO: Add this to the specification
701 // ERROR RECOVERY: If there is no type argument list then just make
702 // this a simple type. TODO: Should this be an error at parse time? what
703 // about at type checking time?
704 let keyword = self.assert_token(TokenKind::Vec);
705 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
706 S!(make_simple_type_specifier, self, keyword)
708 let left = self.assert_left_angle_in_type_list_with_possible_attribute();
709 let t = self.parse_type_specifier(false, true);
710 let optional_comma = self.optional_token(TokenKind::Comma);
711 let right = self.require_right_angle();
713 make_vector_type_specifier,
724 fn parse_keyset_type_specifier(&mut self) -> S::R {
725 // keyset < type-specifier >
726 // TODO: Should we allow a trailing comma?
727 // TODO: Add this to the specification
728 // ERROR RECOVERY: If there is no type argument list then just make
729 // this a simple type. TODO: Should this be an error at parse time? what
730 // about at type checking time?
731 let keyword = self.assert_token(TokenKind::Keyset);
732 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
733 S!(make_simple_type_specifier, self, keyword)
735 let left = self.assert_left_angle_in_type_list_with_possible_attribute();
736 let t = self.parse_type_specifier(false, true);
737 let comma = self.optional_token(TokenKind::Comma);
738 let right = self.require_right_angle();
740 make_keyset_type_specifier,
751 fn parse_tuple_type_explicit_specifier(&mut self) -> S::R {
752 // tuple < type-specifier-list >
753 // TODO: Add this to the specification
754 let keyword = self.assert_token(TokenKind::Tuple);
755 let left_angle = if self.peek_next_partial_token_is_triple_left_angle() {
756 self.assert_left_angle_in_type_list_with_possible_attribute()
758 self.require_left_angle()
760 let args = self.parse_type_list(TokenKind::GreaterThan);
761 let mut parser1 = self.clone();
762 let right_angle = parser1.next_token();
763 if right_angle.kind() == TokenKind::GreaterThan {
764 self.continue_from(parser1);
765 let token = S!(make_token, self, right_angle);
767 make_tuple_type_explicit_specifier,
775 // ERROR RECOVERY: Don't eat the token that is in the place of the
776 // missing > or ,. TokenKind::Assume that it is the > that is missing and
777 // try to parse whatever is coming after the type.
778 self.with_error(Errors::error1022);
779 let right_angle = S!(make_missing, self, self.pos());
781 make_tuple_type_explicit_specifier,
791 fn parse_dictionary_type_specifier(&mut self) -> S::R {
792 // dict < type-specifier , type-specifier >
794 // TODO: Add this to the specification
796 // Though we require there to be exactly two items, we actually parse
797 // an arbitrary comma-separated list here.
799 // TODO: Give an error in a later pass if there are not exactly two members.
801 // ERROR RECOVERY: If there is no type argument list then just make this
802 // a simple type. TODO: Should this be an error at parse time? what
803 // about at type checking time?
804 let keyword = self.assert_token(TokenKind::Dict);
805 if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
806 S!(make_simple_type_specifier, self, keyword)
808 // TODO: This allows "noreturn" as a type argument. Should we
809 // disallow that at parse time?
810 let left = self.assert_left_angle_in_type_list_with_possible_attribute();
811 let (arguments, _) = self.parse_comma_list_allow_trailing(
812 TokenKind::GreaterThan,
814 |x: &mut Self| x.parse_return_type(),
816 let right = self.require_right_angle();
818 make_dictionary_type_specifier,
828 fn parse_tuple_or_closure_type_specifier(&mut self) -> S::R {
829 let mut parser1 = self.clone();
830 let _ = parser1.assert_token(TokenKind::LeftParen);
831 let token = parser1.peek_token();
833 TokenKind::Function | TokenKind::Coroutine => self.parse_closure_type_specifier(),
834 _ => self.parse_tuple_type_specifier(),
838 fn parse_closure_type_specifier(&mut self) -> S::R {
841 // TODO: Update the specification with closure-param-type-specifier-list-opt.
842 // (This work is tracked by task T22582676.)
844 // TODO: Update grammar for inout parameters.
845 // (This work is tracked by task T22582715.)
847 // closure-type-specifier:
848 // ( coroutine-opt function ( \
849 // closure-param-type-specifier-list-opt \
850 // ) : type-specifier )
852 // TODO: Error recovery is pretty weak here. We could be smarter.
853 let olp = self.fetch_token();
854 let coroutine = self.optional_token(TokenKind::Coroutine);
855 let fnc = self.fetch_token();
856 let ilp = self.require_left_paren();
857 let (pts, irp) = if self.peek_token_kind() == TokenKind::RightParen {
858 let missing = S!(make_missing, self, self.pos());
859 let token = self.next_token();
860 let token = S!(make_token, self, token);
863 // TODO add second pass checking to ensure ellipsis is the last arg
864 let pts = self.parse_closure_param_list(TokenKind::RightParen);
865 let irp = self.require_right_paren();
868 let col = self.require_colon();
869 let ret = self.parse_type_specifier(false, true);
870 let orp = self.require_right_paren();
872 make_closure_type_specifier,
886 fn parse_tuple_type_specifier(&mut self) -> S::R {
888 // tuple-type-specifier:
889 // ( type-specifier , type-specifier-list )
890 // type-specifier-list:
891 // type-specifiers ,opt
894 // type-specifiers , type-specifier
896 // TODO: Here we parse a type list with one or more items, but the grammar
897 // actually requires a type list with two or more items. Give an error in
898 // a later pass if there is only one item here.
900 let left_paren = self.assert_token(TokenKind::LeftParen);
901 let args = self.parse_type_list(TokenKind::RightParen);
902 if self.peek_token_kind() == TokenKind::RightParen {
903 let right_paren = self.next_token();
904 let token = S!(make_token, self, right_paren);
905 S!(make_tuple_type_specifier, self, left_paren, args, token)
907 // ERROR RECOVERY: Don't eat the token that is in the place of the
908 // missing ) or ,. Assume that it is the ) that is missing and
909 // try to parse whatever is coming after the type.
910 self.with_error(Errors::error1022);
911 let missing = S!(make_missing, self, self.pos());
912 S!(make_tuple_type_specifier, self, left_paren, args, missing)
916 fn parse_nullable_type_specifier(&mut self) -> S::R {
918 // nullable-type-specifier:
922 // Note that we parse "mixed" as a simple type specifier, even though
923 // technically it is classified as a nullable type specifier by the grammar.
924 // Note that it is perfectly legal to have trivia between the ? and the
926 let question = self.assert_token(TokenKind::Question);
927 let nullable_type = self.parse_type_specifier(false, true);
928 S!(make_nullable_type_specifier, self, question, nullable_type)
931 fn parse_like_type_specifier(&mut self) -> S::R {
933 // like-type-specifier:
936 // Note that it is perfectly legal to have trivia between the ~ and the
938 let tilde = self.assert_token(TokenKind::Tilde);
939 let like_type = self.parse_type_specifier(false, true);
940 S!(make_like_type_specifier, self, tilde, like_type)
943 fn parse_soft_type_specifier(&mut self) -> S::R {
945 // soft-type-specifier:
948 // TODO: The spec does not mention this type grammar. Work out where and
949 // when it is legal, and what the exact semantics are, and put it in the spec.
950 // Add an error pass if necessary to identify illegal usages of this type.
952 // Note that it is legal for trivia to come between the @ and the type.
953 let soft_at = self.assert_token(TokenKind::At);
954 let soft_type = self.parse_type_specifier(false, true);
955 S!(make_soft_type_specifier, self, soft_at, soft_type)
958 fn parse_attributized_specifier(&mut self) -> S::R {
960 // attributized-specifier:
961 // attribute-specification-opt type-specifier
962 let attribute_spec_opt = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
963 x.parse_attribute_specification_opt()
965 let attributized_type = self.parse_type_specifier(false, true);
967 make_attributized_specifier,
974 fn parse_classname_type_specifier(&mut self) -> S::R {
976 // classname-type-specifier:
978 // classname < qualified-name generic-type-argument-list-opt >
980 // TODO: We parse any type as the class name type; we should write an
981 // error detection pass later that determines when this is a bad type.
983 // TODO: Is this grammar correct? In particular, can the name have a
984 // scope resolution operator (::) in it? Find out and update the spec if
985 // this is permitted.
987 // TODO ERROR RECOVERY is unsophisticated here.
988 let classname = self.fetch_token();
989 match self.peek_token_kind() {
990 TokenKind::LessThan => {
991 let left_angle = self.require_left_angle();
992 let classname_type = self.parse_type_specifier(false, true);
993 let optional_comma = self.optional_token(TokenKind::Comma);
994 let right_angle = self.require_right_angle();
996 make_classname_type_specifier,
1006 let missing1 = S!(make_missing, self, self.pos());
1007 let missing2 = S!(make_missing, self, self.pos());
1008 let missing3 = S!(make_missing, self, self.pos());
1009 let missing4 = S!(make_missing, self, self.pos());
1011 make_classname_type_specifier,
1023 fn parse_field_specifier(&mut self) -> S::R {
1026 // ?-opt present-field-specifier
1027 // present-field-specifier:
1028 // single-quoted-string-literal => type-specifier
1029 // qualified-name => type-specifier
1030 // scope-resolution-expression => type-specifier
1032 // TODO: We require that it be either all literals or no literals in the
1033 // set of specifiers; make an error reporting pass that detects this.
1035 // ERROR RECOVERY: We allow any expression for the left-hand side.
1036 // TODO: Make an error-detecting pass that gives an error if the left-hand
1037 // side is not a literal or name.
1038 let question = if self.peek_token_kind() == TokenKind::Question {
1039 self.assert_token(TokenKind::Question)
1041 S!(make_missing, self, self.pos())
1043 let name = self.parse_expression();
1044 let arrow = self.require_arrow();
1045 let field_type = self.parse_type_specifier(false, true);
1047 make_field_specifier,
1056 fn parse_shape_specifier(&mut self) -> S::R {
1059 // shape ( field-specifier-list-opt )
1060 // field-specifier-list:
1061 // field-specifiers , ...
1062 // field-specifiers ,-opt
1063 // field-specifiers:
1065 // field-specifiers , field-specifier
1067 // TODO: ERROR RECOVERY is not very sophisticated here.
1068 let shape = self.fetch_token();
1069 let lparen = self.require_left_paren();
1070 let is_closing_token =
1071 |x: TokenKind| x == TokenKind::RightParen || x == TokenKind::DotDotDot;
1072 let fields = self.parse_comma_list_opt_allow_trailing_predicate(
1075 |x: &mut Self| x.parse_field_specifier(),
1077 let ellipsis = if self.peek_token_kind() == TokenKind::DotDotDot {
1078 self.assert_token(TokenKind::DotDotDot)
1080 S!(make_missing, self, self.pos())
1082 let rparen = self.require_right_paren();
1084 make_shape_type_specifier,
1094 pub fn parse_type_constraint_opt(&mut self) -> S::R {
1097 // as type-specifier
1098 // TODO: Is this correct? Or do we need to allow "super" as well?
1099 // TODO: What about = ?
1100 if self.peek_token_kind() == TokenKind::As {
1101 let constraint_as = self.next_token();
1102 let constraint_as = S!(make_token, self, constraint_as);
1103 let constraint_type = self.parse_type_specifier(false, true);
1104 S!(make_type_constraint, self, constraint_as, constraint_type)
1106 S!(make_missing, self, self.pos())
1110 pub fn parse_return_type(&mut self) -> S::R {
1111 if self.peek_token_kind() == TokenKind::Noreturn {
1112 let token = self.next_token();
1113 S!(make_token, self, token)
1115 self.parse_type_specifier(false, true)