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::expression_parser::ExpressionParser;
8 use crate::lexer::Lexer;
9 use crate::parser_env::ParserEnv;
10 use crate::parser_trait::{Context, ExpectedTokens, ParserTrait, SeparatedListKind};
11 use crate::smart_constructors::{NodeType, SmartConstructors};
12 use crate::statement_parser::StatementParser;
13 use crate::type_parser::TypeParser;
14 use parser_core_types::lexable_token::LexableToken;
15 use parser_core_types::lexable_trivia::LexableTrivia;
16 use parser_core_types::syntax_error::{self as Errors, SyntaxError};
17 use parser_core_types::token_kind::TokenKind;
18 use parser_core_types::trivia_kind::TriviaKind;
21 pub struct DeclarationParser<'a, S, T>
23 S: SmartConstructors<'a, T>,
26 lexer: Lexer<'a, S::Token>,
28 context: Context<'a, S::Token>,
29 errors: Vec<SyntaxError>,
33 impl<'a, S, T: Clone> Clone for DeclarationParser<'a, S, T>
35 S: SmartConstructors<'a, T>,
38 fn clone(&self) -> Self {
40 lexer: self.lexer.clone(),
41 env: self.env.clone(),
42 context: self.context.clone(),
43 errors: self.errors.clone(),
49 impl<'a, S, T: Clone> ParserTrait<'a, S, T> for DeclarationParser<'a, S, T>
51 S: SmartConstructors<'a, T>,
55 lexer: Lexer<'a, S::Token>,
57 context: Context<'a, S::Token>,
58 errors: Vec<SyntaxError>,
74 Context<'a, S::Token>,
78 (self.lexer, self.context, self.errors, self.sc)
81 fn lexer(&self) -> &Lexer<'a, S::Token> {
85 fn lexer_mut(&mut self) -> &mut Lexer<'a, S::Token> {
89 fn continue_from<P: ParserTrait<'a, S, T>>(&mut self, other: P)
93 let (lexer, context, errors, sc) = other.into_parts();
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> DeclarationParser<'a, S, T>
131 S: SmartConstructors<'a, T>,
134 fn with_type_parser<F, U>(&mut self, f: F) -> U
137 F: Fn(&mut TypeParser<'a, S, T>) -> U,
139 let mut type_parser: TypeParser<S, T> = TypeParser::make(
142 self.context.clone(),
146 let res = f(&mut type_parser);
147 self.continue_from(type_parser);
151 fn parse_type_specifier(&mut self, allow_var: bool, allow_attr: bool) -> S::R {
152 self.with_type_parser(|p: &mut TypeParser<'a, S, T>| {
153 p.parse_type_specifier(allow_var, allow_attr)
157 fn with_statement_parser<F, U>(&mut self, f: F) -> U
160 F: Fn(&mut StatementParser<'a, S, T>) -> U,
162 let mut statement_parser: StatementParser<S, T> = StatementParser::make(
165 self.context.clone(),
169 let res = f(&mut statement_parser);
170 self.continue_from(statement_parser);
174 fn parse_simple_type_or_type_constant(&mut self) -> S::R {
175 self.with_type_parser(|x: &mut TypeParser<'a, S, T>| x.parse_simple_type_or_type_constant())
178 fn parse_simple_type_or_generic(&mut self) -> S::R {
179 self.with_type_parser(|p: &mut TypeParser<'a, S, T>| p.parse_simple_type_or_generic())
182 fn with_expression_parser<F, U>(&mut self, f: F) -> U
185 F: Fn(&mut ExpressionParser<'a, S, T>) -> U,
187 let mut expression_parser: ExpressionParser<S, T> = ExpressionParser::make(
190 self.context.clone(),
194 let res = f(&mut expression_parser);
195 self.continue_from(expression_parser);
199 fn parse_expression(&mut self) -> S::R {
200 self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| p.parse_expression())
203 fn parse_compound_statement(&mut self) -> S::R {
204 self.with_statement_parser(|p: &mut StatementParser<'a, S, T>| p.parse_compound_statement())
207 fn parse_enumerator_list_opt(&mut self) -> S::R {
211 // enumerator-list enumerator
213 self.parse_terminated_list(|x: &mut Self| x.parse_enumerator(), TokenKind::RightBrace)
216 fn parse_enum_declaration(&mut self, attrs: S::R) -> S::R {
219 // attribute-specification-opt enum name enum-base type-constraint-opt /
220 // { enumerator-list-opt }
225 // TODO: SPEC ERROR: The spec states that the only legal enum types
226 // are "int" and "string", but Hack allows any type, and apparently
227 // some of those are meaningful and desired. Figure out what types
228 // are actually legal and illegal as enum base types; put them in the
229 // spec, and add an error pass that says when they are wrong.
230 let enum_ = self.assert_token(TokenKind::Enum);
231 let name = self.require_name();
232 let colon = self.require_colon();
234 self.parse_type_specifier(false /* allow_var */, true /* allow_attr */);
235 let enum_type = self.parse_type_constraint_opt();
236 let (left_brace, enumerators, right_brace) =
237 self.parse_braced_list(|x: &mut Self| x.parse_enumerator_list_opt());
239 make_enum_declaration,
253 fn parse_record_field(&mut self) -> S::R {
256 // record-constant : type field-initializer-opt,
259 // field-initializer:
261 let name = self.require_name_allow_non_reserved();
262 let colon = self.require_colon();
263 let field_type = self.parse_type_specifier(false, true);
264 let init = self.parse_simple_initializer_opt();
265 let comma = self.require_comma();
277 fn parse_record_fields(&mut self) -> S::R {
281 // record-list record-field
282 self.parse_terminated_list(|x| x.parse_record_field(), TokenKind::RightBrace)
285 fn parse_record_declaration(&mut self, attrs: S::R) -> S::R {
286 // record-declaration:
287 // (abstract|final) record name { record-list }
289 self.require_token_one_of(&[TokenKind::Abstract, TokenKind::Final], Errors::error1037);
290 let record = self.assert_token(TokenKind::RecordDec);
291 let name = self.require_name();
292 let (record_extends, record_extends_list) = self.parse_extends_opt();
293 let (left_brace, record_fields, right_brace) =
294 self.parse_braced_list(|x| x.parse_record_fields());
296 make_record_declaration,
310 pub fn parse_leading_markup_section(&mut self) -> Option<S::R> {
311 let mut parser1 = self.clone();
312 let (markup_section, has_suffix) =
313 parser1.with_statement_parser(|p: &mut StatementParser<'a, S, T>| p.parse_header());
314 // proceed successfully if we've consumed <?..., or dont need it
315 // We purposefully ignore leading trivia before the <?hh, and handle
316 // the error on a later pass
318 self.continue_from(parser1);
321 if self.lexer().source().length() > 0
322 && self.lexer().source().file_path().ends_with(".php")
324 self.with_error(Errors::error1001);
330 fn parse_namespace_body(&mut self) -> S::R {
331 match self.peek_token_kind() {
332 TokenKind::Semicolon => {
333 let token = self.fetch_token();
334 S!(make_namespace_empty_body, self, token)
336 TokenKind::LeftBrace => {
337 let left = self.fetch_token();
338 let body = self.parse_terminated_list(
339 |x: &mut Self| x.parse_declaration(),
340 TokenKind::RightBrace,
342 let right = self.require_right_brace();
343 S!(make_namespace_body, self, left, body, right)
346 // ERROR RECOVERY: return an inert namespace (one with all of its
347 // components 'missing'), and recover--without advancing the parser--
348 // back to the level that the namespace was declared in.
349 self.with_error(Errors::error1038);
350 let missing1 = S!(make_missing, self, self.pos());
351 let missing2 = S!(make_missing, self, self.pos());
352 let missing3 = S!(make_missing, self, self.pos());
353 S!(make_namespace_body, self, missing1, missing2, missing3)
358 fn is_group_use(&self) -> bool {
359 let mut parser = self.clone();
360 // We want a heuristic to determine whether to parse the use clause as
361 // a group use or normal use clause. We distinguish the two by (1) whether
362 // there is a namespace prefix -- in this case it is definitely a group use
363 // clause -- or, if there is a name followed by a curly. That's illegal, but
364 // we should give an informative error message about that.
365 parser.assert_token(TokenKind::Use);
366 parser.parse_namespace_use_kind_opt();
367 let token = parser.next_token();
369 TokenKind::Backslash => {
370 let missing = S!(make_missing, parser, parser.pos());
371 let backslash = S!(make_token, parser, token);
372 let (_name, is_backslash) = parser.scan_qualified_name_extended(missing, backslash);
373 is_backslash || parser.peek_token_kind() == TokenKind::LeftBrace
376 let token = S!(make_token, parser, token);
377 let roken_ref = &token as *const _;
378 let (name, is_backslash) = parser.scan_remaining_qualified_name_extended(token);
379 // Here we rely on the implementation details of
380 // scan_remaining_qualified_name_extended. It's returning
381 // *exactly* token if there is nothing except it in the name.
382 is_backslash && (&name as *const _ == roken_ref)
383 || parser.peek_token_kind() == TokenKind::LeftBrace
389 fn parse_namespace_use_kind_opt(&mut self) -> S::R {
391 // namespace-use-kind:
395 let mut parser1 = self.clone();
396 let token = parser1.next_token();
398 TokenKind::Type | TokenKind::Namespace | TokenKind::Function | TokenKind::Const => {
399 self.continue_from(parser1);
400 S!(make_token, self, token)
402 _ => S!(make_missing, self, self.pos()),
406 fn parse_group_use(&mut self) -> S::R {
407 // See below for grammar.
408 let use_token = self.assert_token(TokenKind::Use);
409 let use_kind = self.parse_namespace_use_kind_opt();
410 // We already know that this is a name, qualified name, or prefix.
411 // If this is not a prefix, it will be detected as an error in a later pass
412 let prefix = self.scan_name_or_qualified_name();
413 let (left, clauses, right) =
414 self.parse_braced_comma_list_opt_allow_trailing(|x: &mut Self| {
415 x.parse_namespace_use_clause()
417 let semi = self.require_semicolon();
419 make_namespace_group_use_declaration,
431 fn parse_namespace_use_clause(&mut self) -> S::R {
433 // namespace-use-clause:
434 // qualified-name namespace-aliasing-clauseopt
435 // namespace-use-kind-clause:
436 // namespace-use-kind-opt qualified-name namespace-aliasing-clauseopt
437 // namespace-aliasing-clause:
440 let use_kind = self.parse_namespace_use_kind_opt();
441 let name = self.require_qualified_name();
442 let (as_token, alias) = if self.peek_token_kind() == TokenKind::As {
443 let as_token = self.next_token();
444 let as_token = S!(make_token, self, as_token);
445 let alias = self.require_name();
448 let missing1 = S!(make_missing, self, self.pos());
449 let missing2 = S!(make_missing, self, self.pos());
453 make_namespace_use_clause,
462 fn parse_namespace_use_declaration(&mut self) -> S::R {
464 // namespace-use-declaration:
465 // use namespace-use-kind-opt namespace-use-clauses ;
466 // use namespace-use-kind namespace-name-as-a-prefix
467 // { namespace-use-clauses } ;
468 // use namespace-name-as-a-prefix { namespace-use-kind-clauses } ;
470 // TODO: Add the grammar for the namespace-use-clauses; ensure that it
471 // indicates that trailing commas are allowed in the list.
474 // In the "simple" format, the kind may only be specified up front.
476 // The grammar in the specification says that in the "group"
477 // format, if the kind is specified up front then it may not
478 // be specified in each clause. However, HHVM's parser disallows
479 // the kind in each clause regardless of whether it is specified up front.
480 // We will fix the specification to match HHVM.
482 // The grammar in the specification also says that in the "simple" format,
483 // the kind may only be specified up front. But HHVM allows the kind to
484 // be specified in each clause. Again, we will fix the specification to match
487 // TODO: Update the grammar comment above when the specification is fixed.
488 // (This work is being tracked by spec work items 102, 103 and 104.)
490 // We do not enforce these rules here. Rather, we allow the kind to be anywhere,
491 // and detect the errors in a later pass.
492 if self.is_group_use() {
493 self.parse_group_use()
495 let use_token = self.assert_token(TokenKind::Use);
496 let use_kind = self.parse_namespace_use_kind_opt();
497 let (clauses, _) = self.parse_comma_list_allow_trailing(
498 TokenKind::Semicolon,
500 |x: &mut Self| x.parse_namespace_use_clause(),
502 let semi = self.require_semicolon();
504 make_namespace_use_declaration,
514 fn parse_namespace_declaration(&mut self) -> S::R {
516 // namespace-definition:
517 // namespace namespace-name ;
518 // namespace namespace-name-opt { declaration-list }
520 // TODO: An error case not caught by the parser that should be caught
522 // Qualified names are a superset of legal namespace names.
523 let namespace_token = self.assert_token(TokenKind::Namespace);
524 let name = match self.peek_token_kind() {
526 let token = self.next_token();
527 let token = S!(make_token, self, token);
528 self.scan_remaining_qualified_name(token)
530 TokenKind::LeftBrace => S!(make_missing, self, self.pos()),
531 TokenKind::Semicolon => {
532 // ERROR RECOVERY Plainly the name is missing.
533 self.with_error(Errors::error1004);
534 S!(make_missing, self, self.pos())
537 // TODO: Death to PHPisms; keywords as namespace names
539 self.require_name_allow_non_reserved()
542 let body = self.parse_namespace_body();
544 make_namespace_declaration,
552 pub fn parse_classish_declaration(&mut self, attribute_spec: S::R) -> S::R {
553 let modifiers = self.parse_classish_modifiers();
554 let token = self.parse_classish_token();
555 let name = self.require_class_name();
556 let generic_type_parameter_list = self.parse_generic_type_parameter_list_opt();
557 let (classish_extends, classish_extends_list) = self.parse_extends_opt();
558 let (classish_implements, classish_implements_list) = self.parse_classish_implements_opt();
559 let classish_where_clause = self.parse_classish_where_clause_opt();
560 let body = self.parse_classish_body();
562 make_classish_declaration,
568 generic_type_parameter_list,
570 classish_extends_list,
572 classish_implements_list,
573 classish_where_clause,
578 fn parse_classish_where_clause_opt(&mut self) -> S::R {
579 if self.peek_token_kind() == TokenKind::Where {
580 self.parse_where_clause()
582 S!(make_missing, self, self.pos())
586 fn parse_classish_implements_opt(&mut self) -> (S::R, S::R) {
587 if self.peek_token_kind() != TokenKind::Implements {
588 let missing1 = S!(make_missing, self, self.pos());
589 let missing2 = S!(make_missing, self, self.pos());
592 let implements_token = self.next_token();
593 let implements_token = S!(make_token, self, implements_token);
594 let implements_list = self.parse_special_type_list();
595 (implements_token, implements_list)
599 fn parse_classish_modifiers(&mut self) -> S::R {
600 let mut acc = vec![];
602 match self.peek_token_kind() {
603 TokenKind::Abstract | TokenKind::Final => {
605 let token = self.next_token();
606 let token = S!(make_token, self, token);
609 _ => return S!(make_list, self, acc, self.pos()),
614 fn parse_classish_token(&mut self) -> S::R {
615 let spellcheck_tokens = vec![TokenKind::Class, TokenKind::Trait, TokenKind::Interface];
616 let token_str = &self.current_token_text();
617 let token_kind = self.peek_token_kind();
619 TokenKind::Class | TokenKind::Trait | TokenKind::Interface => {
620 let token = self.next_token();
621 S!(make_token, self, token)
624 TokenKind::Name if Self::is_misspelled_from(&spellcheck_tokens, token_str) => {
625 // Default won't be used, since we already checked is_misspelled_from
626 let suggested_kind = Self::suggested_kind_from(&spellcheck_tokens, token_str)
627 .unwrap_or(TokenKind::Name);
628 self.skip_and_log_misspelled_token(suggested_kind);
629 S!(make_missing, self, self.pos())
632 self.with_error(Errors::error1035);
633 S!(make_missing, self, self.pos())
638 fn parse_special_type(&mut self) -> (S::R, bool) {
639 let mut parser1 = self.clone();
640 let token = parser1.next_xhp_class_name_or_other_token();
642 TokenKind::Comma => {
643 // ERROR RECOVERY. We expected a type but we got a comma.
644 // Give the error that we expected a type, not a name, even though
645 // not every type is legal here.
646 self.continue_from(parser1);
647 self.with_error(Errors::error1007);
648 let comma = S!(make_token, self, token);
649 let missing = S!(make_missing, self, self.pos());
650 let list_item = S!(make_list_item, self, missing, comma);
654 | TokenKind::Namespace
656 | TokenKind::XHPClassName => {
658 .parse_type_specifier(false /* allow_var */, true /* allow_attr */);
659 let comma = self.optional_token(TokenKind::Comma);
660 let is_missing = comma.is_missing();
661 let list_item = S!(make_list_item, self, item, comma);
662 (list_item, is_missing)
666 | TokenKind::RecordDec
668 | TokenKind::SelfToken
669 if self.env.hhvm_compat_mode =>
671 // HHVM allows these keywords here for some reason
672 let item = self.parse_simple_type_or_type_constant();
673 let comma = self.optional_token(TokenKind::Comma);
674 let is_missing = comma.is_missing();
675 let list_item = S!(make_list_item, self, item, comma);
676 (list_item, is_missing)
679 // ERROR RECOVERY: We are expecting a type; give an error as above.
680 // Don't eat the offending token.
681 self.with_error(Errors::error1007);
682 let missing1 = S!(make_missing, self, self.pos());
683 let missing2 = S!(make_missing, self, self.pos());
684 let list_item = S!(make_list_item, self, missing1, missing2);
690 fn parse_special_type_list(&mut self) -> S::R {
691 // An extends / implements list is a comma-separated list of types, but
692 // very special types; we want the types to consist of a name and an
693 // optional generic type argument list.
695 // TODO: Can the type name be of the form "foo::bar"? Those do not
696 // necessarily start with names. Investigate this.
698 // Normally we'd use one of the separated list helpers, but there is no
699 // specific end token we could use to detect the end of the list, and we
700 // want to bail out if we get something that is not a type of the right form.
701 // So we have custom logic here.
703 // TODO: This is one of the rare cases in Hack where a comma-separated list
704 // may not have a trailing comma. Is that desirable, or was that an
705 // oversight when the trailing comma rules were added? If possible we
706 // should keep the rule as-is, and disallow the trailing comma; it makes
707 // parsing and error recovery easier.
708 let mut items = vec![];
710 let (item, is_missing) = self.parse_special_type();
717 S!(make_list, self, items, self.pos())
720 fn parse_extends_opt(&mut self) -> (S::R, S::R) {
721 let token_kind = self.peek_token_kind();
722 if token_kind != TokenKind::Extends {
723 let missing1 = S!(make_missing, self, self.pos());
724 let missing2 = S!(make_missing, self, self.pos());
727 let token = self.next_token();
728 let extends_token = S!(make_token, self, token);
729 let extends_list = self.parse_special_type_list();
730 (extends_token, extends_list)
734 fn parse_classish_body(&mut self) -> S::R {
735 let left_brace_token = self.require_left_brace();
736 let classish_element_list = self.parse_classish_element_list_opt();
737 let right_brace_token = self.require_right_brace();
742 classish_element_list,
747 fn parse_classish_element_list_opt(&mut self) -> S::R {
748 // TODO: ERROR RECOVERY: consider bailing if the token cannot possibly
749 // start a classish element.
750 // ERROR RECOVERY: we're in the body of a classish, so we add visibility
751 // modifiers to our context.
752 self.expect_in_new_scope(ExpectedTokens::Visibility);
753 let element_list = self.parse_terminated_list(
754 |x: &mut Self| x.parse_classish_element(),
755 TokenKind::RightBrace,
757 self.pop_scope(ExpectedTokens::Visibility);
761 fn parse_xhp_children_paren(&mut self) -> S::R {
763 // ( xhp-children-expressions )
765 // xhp-children-expressions:
766 // xhp-children-expression
767 // xhp-children-expressions , xhp-children-expression
769 // TODO: The parenthesized list of children expressions is NOT allowed
770 // to be comma-terminated. Is this intentional? It is inconsistent with
771 // practice throughout the rest of Hack. There is no syntactic difficulty
772 // in allowing a comma before the close paren. Consider allowing it.
773 let (left, exprs, right) =
774 self.parse_parenthesized_comma_list(|x: &mut Self| x.parse_xhp_children_expression());
776 make_xhp_children_parenthesized_list,
784 fn parse_xhp_children_term(&mut self) -> S::R {
786 // xhp-children-term:
787 // ( xhp-children-expressions ) trailing-opt
789 // xhp-class-name trailing-opt
790 // xhp-category-name trailing-opt
793 // Note that there may be only zero or one trailing unary operator.
794 // "foo*?" is not a legal xhp child expression.
796 let mut parser1 = self.clone();
797 let token = parser1.next_xhp_children_name_or_other();
798 let kind = token.kind();
799 let name = S!(make_token, parser1, token);
801 TokenKind::Name | TokenKind::XHPClassName | TokenKind::XHPCategoryName => {
802 self.continue_from(parser1);
803 self.parse_xhp_children_trailing(name)
805 TokenKind::LeftParen => {
806 let term = self.parse_xhp_children_paren();
807 self.parse_xhp_children_trailing(term)
810 // ERROR RECOVERY: Eat the offending token, keep going.
811 self.with_error(Errors::error1053);
817 fn parse_xhp_children_trailing(&mut self, term: S::R) -> S::R {
818 let token_kind = self.peek_token_kind();
820 TokenKind::Star | TokenKind::Plus | TokenKind::Question => {
821 let token = self.next_token();
822 let token = S!(make_token, self, token);
823 S!(make_postfix_unary_expression, self, term, token)
829 fn parse_xhp_children_bar(&mut self, left: S::R) -> S::R {
830 let token_kind = self.peek_token_kind();
833 let token = self.next_token();
834 let token = S!(make_token, self, token);
835 let right = self.parse_xhp_children_term();
836 let result = S!(make_binary_expression, self, left, token, right);
837 self.parse_xhp_children_bar(result)
843 fn parse_xhp_children_expression(&mut self) -> S::R {
845 // xhp-children-expression:
847 // xhp-children-expression | xhp-children-term
849 // Note that the bar operator is left-associative. (Not that it matters
851 let term = self.parse_xhp_children_term();
852 self.parse_xhp_children_bar(term)
855 fn parse_xhp_children_declaration(&mut self) -> S::R {
857 // xhp-children-declaration:
859 // children xhp-children-expression ;
860 let children = self.assert_token(TokenKind::Children);
861 let token_kind = self.peek_token_kind();
862 let expr = match token_kind {
863 TokenKind::Empty => {
864 let token = self.next_token();
865 S!(make_token, self, token)
867 _ => self.parse_xhp_children_expression(),
869 let semi = self.require_semicolon();
870 S!(make_xhp_children_declaration, self, children, expr, semi)
873 fn parse_xhp_category(&mut self) -> S::R {
874 let token = self.next_xhp_category_name();
875 let token_kind = token.kind();
876 let category = S!(make_token, self, token);
878 TokenKind::XHPCategoryName => category,
880 self.with_error(Errors::error1052);
886 fn parse_xhp_type_specifier(&mut self) -> S::R {
888 // xhp-type-specifier:
889 // enum { xhp-attribute-enum-list ,-opt }
892 // The list of enum values must have at least one value and can be
896 // xhp-attribute-enum-value
897 // xhp-enum-list , xhp-attribute-enum-value
899 // xhp-attribute-enum-value:
900 // any integer literal
901 // any single-quoted-string literal
902 // any double-quoted-string literal
904 // TODO: What are the semantics of encapsulated expressions in double-quoted
905 // string literals here?
906 // ERROR RECOVERY: We parse any expressions here;
907 // TODO: give an error in a later pass if the expressions are not literals.
908 // (This work is tracked by task T21175355)
910 // An empty list is illegal, but we allow it here and give an error in
912 let mut parser1 = self.clone();
913 let token = parser1.next_token();
914 let (token, optional) = match token.kind() {
915 TokenKind::Question => {
916 let enum_token = parser1.next_token();
917 let token = S!(make_token, parser1, token);
921 let missing = S!(make_missing, parser1, self.pos());
927 self.continue_from(parser1);
928 let enum_token = S!(make_token, self, token);
929 let (left_brace, values, right_brace) = self
930 .parse_braced_comma_list_opt_allow_trailing(|x: &mut Self| {
943 _ => self.parse_type_specifier(true, true),
947 fn parse_xhp_required_opt(&mut self) -> S::R {
950 // @ (required | lateinit)
952 // Note that these are two tokens. They can have whitespace between them.
953 if self.peek_token_kind() == TokenKind::At {
954 let at = self.assert_token(TokenKind::At);
955 let req_kind = self.next_token();
956 let kind = req_kind.kind();
957 let req = S!(make_token, self, req_kind);
959 TokenKind::Required => S!(make_xhp_required, self, at, req),
960 TokenKind::Lateinit => S!(make_xhp_lateinit, self, at, req),
962 self.with_error(Errors::error1051);
963 S!(make_missing, self, self.pos())
967 S!(make_missing, self, self.pos())
971 fn parse_xhp_class_attribute_typed(&mut self) -> S::R {
972 // xhp-type-specifier xhp-name initializer-opt xhp-required-opt
973 let ty = self.parse_xhp_type_specifier();
974 let name = self.require_xhp_name();
975 let init = self.parse_simple_initializer_opt();
976 let req = self.parse_xhp_required_opt();
977 S!(make_xhp_class_attribute, self, ty, name, init, req)
980 fn parse_xhp_category_declaration(&mut self) -> S::R {
982 // xhp-category-declaration:
983 // category xhp-category-list ,-opt ;
985 // xhp-category-list:
987 // xhp-category-list , xhp-category-name
988 let category = self.assert_token(TokenKind::Category);
989 let (items, _) = self.parse_comma_list_allow_trailing(
990 TokenKind::Semicolon,
992 |x: &mut Self| x.parse_xhp_category(),
994 let semi = self.require_semicolon();
995 S!(make_xhp_category_declaration, self, category, items, semi)
998 fn parse_xhp_class_attribute(&mut self) -> S::R {
1000 // xhp-attribute-declaration:
1002 // xhp-type-specifier xhp-name initializer-opt xhp-required-opt
1005 // The xhp type specifier could be an xhp class name. To disambiguate we peek
1006 // ahead a token; if it's a comma or semi, we're done. If not, then we assume
1007 // that we are in the more complex case.
1008 if self.is_next_xhp_class_name() {
1009 let mut parser1 = self.clone();
1010 let class_name = parser1.require_class_name();
1011 match parser1.peek_token_kind() {
1012 TokenKind::Comma | TokenKind::Semicolon => {
1013 self.continue_from(parser1);
1014 let type_specifier = S!(make_simple_type_specifier, self, class_name);
1015 S!(make_xhp_simple_class_attribute, self, type_specifier)
1017 _ => self.parse_xhp_class_attribute_typed(),
1020 self.parse_xhp_class_attribute_typed()
1024 fn parse_xhp_class_attribute_declaration(&mut self) -> S::R {
1026 // xhp-class-attribute-declaration :
1027 // attribute xhp-attribute-declaration-list ;
1029 // xhp-attribute-declaration-list:
1030 // xhp-attribute-declaration
1031 // xhp-attribute-declaration-list , xhp-attribute-declaration
1033 // TODO: The list of attributes may NOT be terminated with a trailing comma
1034 // before the semicolon. This is inconsistent with the rest of Hack.
1035 // Allowing a comma before the semi does not introduce any syntactic
1036 // difficulty; consider allowing it.
1037 let attr_token = self.assert_token(TokenKind::Attribute);
1038 // TODO: Better error message.
1040 self.parse_comma_list(TokenKind::Semicolon, Errors::error1004, |x: &mut Self| {
1041 x.parse_xhp_class_attribute()
1043 let semi = self.require_semicolon();
1045 make_xhp_class_attribute_declaration,
1053 fn parse_qualified_name_type(&mut self) -> S::R {
1054 // Here we're parsing a name followed by an optional generic type
1055 // argument list; if we don't have a name, give an error.
1056 match self.peek_token_kind() {
1057 TokenKind::Backslash | TokenKind::Name => self.parse_simple_type_or_generic(),
1058 _ => self.require_qualified_name(),
1062 fn parse_qualified_name_type_opt(&mut self) -> S::R {
1063 // Here we're parsing a name followed by an optional generic type
1064 // argument list; if we don't have a name, give an error.
1065 match self.peek_token_kind() {
1066 TokenKind::Backslash | TokenKind::Construct | TokenKind::Name => {
1067 self.parse_simple_type_or_generic()
1069 _ => S!(make_missing, self, self.pos()),
1073 fn parse_require_clause(&mut self) -> S::R {
1075 // require-extends-clause:
1076 // require extends qualified-name ;
1078 // require-implements-clause:
1079 // require implements qualified-name ;
1081 // We must also parse "require extends :foo;"
1082 // TODO: What about "require extends :foo<int>;" ?
1083 // TODO: The spec is incomplete; we need to be able to parse
1084 // require extends Foo<int>;
1085 // (This work is being tracked by spec issue 105.)
1086 // TODO: Check whether we also need to handle
1087 // require extends foo::bar
1090 // ERROR RECOVERY: Detect if the implements/extends, name and semi are
1092 let req = self.assert_token(TokenKind::Require);
1093 let token_kind = self.peek_token_kind();
1094 let req_kind = match token_kind {
1095 TokenKind::Implements | TokenKind::Extends => {
1096 let req_kind_token = self.next_token();
1097 S!(make_token, self, req_kind_token)
1100 self.with_error(Errors::error1045);
1101 S!(make_missing, self, self.pos())
1104 let name = if self.is_next_xhp_class_name() {
1105 self.parse_simple_type_or_generic()
1107 self.parse_qualified_name_type()
1109 let semi = self.require_semicolon();
1110 S!(make_require_clause, self, req, req_kind, name, semi)
1113 // This duplicates work from parse_methodish_or_const_or_type_const,
1114 // but this function is only invoked after an attribute spec, while
1115 // parse_methodish_or_const_or_type_const is called after a modifier.
1116 // Having this function prevents constants from having attributes as
1117 // this cannot be checked in parser_errors as there is no field in constant
1118 // declaration to store 'attributes'.
1119 fn parse_methodish_or_property_or_type_constant(&mut self, attribute_spec: S::R) -> S::R {
1120 let mut parser1 = self.clone();
1121 let modifiers = parser1.parse_modifiers();
1122 let current_token_kind = parser1.peek_token_kind();
1123 let next_token = parser1.peek_token_with_lookahead(1);
1124 let next_token_kind = next_token.kind();
1125 match (current_token_kind, next_token_kind) {
1126 (TokenKind::Const, TokenKind::Type) => {
1127 self.continue_from(parser1);
1128 let const_ = self.assert_token(TokenKind::Const);
1129 self.parse_type_const_declaration(attribute_spec, modifiers, const_)
1131 _ => self.parse_methodish_or_property(attribute_spec),
1135 fn has_leading_trivia(token: &S::Token, kind: TriviaKind) -> bool {
1136 token.leading().iter().any(|x| x.kind() == kind)
1139 fn parse_methodish_or_property(&mut self, attribute_spec: S::R) -> S::R {
1140 let modifiers = self.parse_modifiers();
1141 // ERROR RECOVERY: match against two tokens, because if one token is
1142 // in error but the next isn't, then it's likely that the user is
1143 // simply still typing. Throw an error on what's being typed, then eat
1144 // it and keep going.
1145 let current_token_kind = self.peek_token_kind();
1146 let next_token = self.peek_token_with_lookahead(1);
1147 let next_token_kind = next_token.kind();
1148 match (current_token_kind, next_token_kind) {
1149 // Detected the usual start to a method, so continue parsing as method.
1150 (TokenKind::Async, _) | (TokenKind::Coroutine, _) | (TokenKind::Function, _) => {
1151 self.parse_methodish(attribute_spec, modifiers)
1153 (TokenKind::LeftParen, _) => self.parse_property_declaration(attribute_spec, modifiers),
1155 // We encountered one unexpected token, but the next still indicates that
1156 // we should be parsing a methodish. Throw an error, process the token
1157 // as an extra, and keep going.
1158 (_, TokenKind::Async) | (_, TokenKind::Coroutine) | (_, TokenKind::Function)
1159 if !(Self::has_leading_trivia(&next_token, TriviaKind::EndOfLine)) =>
1161 self.with_error_on_whole_token(Errors::error1056);
1162 self.skip_and_log_unexpected_token(false);
1163 self.parse_methodish(attribute_spec, modifiers)
1165 // Otherwise, continue parsing as a property (which might be a lambda).
1166 _ => self.parse_property_declaration(attribute_spec, modifiers),
1170 fn parse_trait_use_precedence_item(&mut self, name: S::R) -> S::R {
1171 let keyword = self.assert_token(TokenKind::Insteadof);
1172 let removed_names = self.parse_trait_name_list(|x: TokenKind| x == TokenKind::Semicolon);
1174 make_trait_use_precedence_item,
1182 fn parse_trait_use_alias_item(&mut self, aliasing_name: S::R) -> S::R {
1183 let keyword = self.require_token(TokenKind::As, Errors::expected_as_or_insteadof);
1184 let modifiers = self.parse_modifiers();
1185 let aliased_name = self.parse_qualified_name_type_opt();
1187 make_trait_use_alias_item,
1196 fn parse_trait_use_conflict_resolution_item(&mut self) -> S::R {
1197 let qualifier = self.parse_qualified_name_type();
1198 let name = if self.peek_token_kind() == TokenKind::ColonColon {
1199 // scope resolution expression case
1200 let cc_token = self.require_coloncolon();
1202 .require_token_one_of(&[TokenKind::Name, TokenKind::Construct], Errors::error1004);
1204 make_scope_resolution_expression,
1211 // plain qualified name case
1214 match self.peek_token_kind() {
1215 TokenKind::Insteadof => self.parse_trait_use_precedence_item(name),
1216 TokenKind::As | _ => self.parse_trait_use_alias_item(name),
1221 // trait-use-conflict-resolution:
1222 // use trait-name-list { trait-use-conflict-resolution-list }
1224 // trait-use-conflict-resolution-list:
1225 // trait-use-conflict-resolution-item
1226 // trait-use-conflict-resolution-item trait-use-conflict-resolution-list
1228 // trait-use-conflict-resolution-item:
1229 // trait-use-alias-item
1230 // trait-use-precedence-item
1232 // trait-use-alias-item:
1233 // trait-use-conflict-resolution-item-name as name;
1234 // trait-use-conflict-resolution-item-name as visibility-modifier name;
1235 // trait-use-conflict-resolution-item-name as visibility-modifier;
1237 // trait-use-precedence-item:
1238 // scope-resolution-expression insteadof trait-name-list
1240 // trait-use-conflict-resolution-item-name:
1242 // scope-resolution-expression
1243 fn parse_trait_use_conflict_resolution(
1246 trait_name_list: S::R,
1248 let left_brace = self.assert_token(TokenKind::LeftBrace);
1249 let clauses = self.parse_separated_list_opt(
1250 TokenKind::Semicolon,
1251 SeparatedListKind::TrailingAllowed,
1252 TokenKind::RightBrace,
1254 |x: &mut Self| x.parse_trait_use_conflict_resolution_item(),
1256 let right_brace = self.require_token(TokenKind::RightBrace, Errors::error1006);
1258 make_trait_use_conflict_resolution,
1269 // trait-use-clause:
1270 // use trait-name-list ;
1273 // qualified-name generic-type-parameter-listopt
1274 // trait-name-list , qualified-name generic-type-parameter-listopt
1275 fn parse_trait_name_list<P>(&mut self, predicate: P) -> S::R
1277 P: Fn(TokenKind) -> bool,
1279 let (items, _) = self.parse_separated_list_predicate(
1281 SeparatedListKind::NoTrailing,
1284 |x: &mut Self| x.parse_qualified_name_type(),
1289 fn parse_trait_use(&mut self) -> S::R {
1290 let use_token = self.assert_token(TokenKind::Use);
1291 let trait_name_list =
1292 self.parse_trait_name_list(|x| x == TokenKind::Semicolon || x == TokenKind::LeftBrace);
1293 if self.peek_token_kind() == TokenKind::LeftBrace {
1294 self.parse_trait_use_conflict_resolution(use_token, trait_name_list)
1296 let semi = self.require_semicolon();
1297 S!(make_trait_use, self, use_token, trait_name_list, semi)
1301 fn parse_property_declaration(&mut self, attribute_spec: S::R, modifiers: S::R) -> S::R {
1303 // property-declaration:
1304 // attribute-spec-opt property-modifier type-specifier
1305 // property-declarator-list ;
1307 // property-declarator-list:
1308 // property-declarator
1309 // property-declarator-list , property-declarator
1311 // The type specifier is optional in non-strict mode and required in
1312 // strict mode. We give an error in a later pass.
1313 let prop_type = match self.peek_token_kind() {
1314 TokenKind::Variable => S!(make_missing, self, self.pos()),
1315 _ => self.parse_type_specifier(false /* allow_var */, false /* allow_attr */),
1318 self.parse_comma_list(TokenKind::Semicolon, Errors::error1008, |x: &mut Self| {
1319 x.parse_property_declarator()
1321 let semi = self.require_semicolon();
1323 make_property_declaration,
1333 fn parse_property_declarator(&mut self) -> S::R {
1335 // property-declarator:
1336 // variable-name property-initializer-opt
1337 // property-initializer:
1339 let name = self.require_variable();
1340 let simple_init = self.parse_simple_initializer_opt();
1341 S!(make_property_declarator, self, name, simple_init)
1344 fn is_type_in_const(&self) -> bool {
1345 let mut parser1 = self.clone();
1346 let _ = parser1.parse_type_specifier(false, true);
1347 let _ = parser1.require_name_allow_all_keywords();
1348 self.errors.len() == parser1.errors.len()
1352 // const-declaration:
1353 // abstract_opt const type-specifier_opt constant-declarator-list ;
1354 // visibility const type-specifier_opt constant-declarator-list ;
1355 // constant-declarator-list:
1356 // constant-declarator
1357 // constant-declarator-list , constant-declarator
1358 // constant-declarator:
1359 // name constant-initializer_opt
1360 // constant-initializer:
1361 // = const-expression
1362 fn parse_const_declaration(&mut self, modifiers: S::R, const_: S::R) -> S::R {
1363 let type_spec = if self.is_type_in_const() {
1364 self.parse_type_specifier(/* allow_var = */ false, /* allow_attr = */ true)
1366 S!(make_missing, self, self.pos())
1370 self.parse_comma_list(TokenKind::Semicolon, Errors::error1004, |x: &mut Self| {
1371 x.parse_constant_declarator()
1373 let semi = self.require_semicolon();
1375 make_const_declaration,
1385 fn parse_constant_declarator(&mut self) -> S::R {
1386 // TODO: We allow const names to be keywords here; in particular we
1387 // require that const string TRUE = "true"; be legal. Likely this
1388 // should be more strict. What are the rules for which keywords are
1389 // legal constant names and which are not?
1390 // Note that if this logic is changed, it should be changed in
1391 // is_type_in_const above as well.
1393 // This permits abstract variables to have an initializer, and vice-versa.
1394 // This is deliberate, and those errors will be detected after the syntax
1396 let const_name = self.require_name_allow_all_keywords();
1397 let initializer_ = self.parse_simple_initializer_opt();
1398 S!(make_constant_declarator, self, const_name, initializer_)
1402 // type-constant-declaration:
1403 // abstract-type-constant-declaration
1404 // concrete-type-constant-declaration
1405 // abstract-type-constant-declaration:
1406 // abstract const type name type-constraintopt ;
1407 // concrete-type-constant-declaration:
1408 // const type name type-constraintopt = type-specifier ;
1412 // An abstract type constant may only occur in an interface or an abstract
1413 // class. We allow that to be parsed here, and the type checker detects the
1415 // CONSIDER: We could detect this error in a post-parse pass; it is entirely
1416 // syntactic. Consider moving the error detection out of the type checker.
1418 // An interface may not contain a non-abstract type constant that has a
1419 // type constraint. We allow that to be parsed here, and the type checker
1420 // detects the error.
1421 // CONSIDER: We could detect this error in a post-parse pass; it is entirely
1422 // syntactic. Consider moving the error detection out of the type checker.
1423 fn parse_type_const_declaration(
1429 let type_token = self.assert_token(TokenKind::Type);
1430 let name = self.require_name_allow_non_reserved();
1431 let generic_type_parameter_list = self.parse_generic_type_parameter_list_opt();
1432 let type_constraint = self.parse_type_constraint_opt();
1433 let (equal_token, type_specifier) = if self.peek_token_kind() == TokenKind::Equal {
1434 let equal_token = self.assert_token(TokenKind::Equal);
1435 let type_spec = self
1436 .parse_type_specifier(/* allow_var = */ false, /* allow_attr = */ true);
1437 (equal_token, type_spec)
1439 let missing1 = S!(make_missing, self, self.pos());
1440 let missing2 = S!(make_missing, self, self.pos());
1441 (missing1, missing2)
1443 let semicolon = self.require_semicolon();
1445 make_type_const_declaration,
1452 generic_type_parameter_list,
1461 // attribute_specification :=
1463 // old_attribute_specification
1464 // attribute_list :=
1466 // attribute_list attribute
1467 // attribute := @ attribute_name attribute_value_list_opt
1468 // old_attribute_specification := << old_attribute_list >>
1469 // old_attribute_list :=
1471 // old_attribute_list , old_attribute
1472 // old_attribute := attribute_name attribute_value_list_opt
1473 // attribute_name := name
1474 // attribute_value_list := ( attribute_values_opt )
1475 // attribute_values :=
1477 // attribute_values , attribute_value
1478 // attribute_value := expression
1480 // TODO: The list of attrs can have a trailing comma. Update the spec.
1481 // TODO: The list of values can have a trailing comma. Update the spec.
1482 // (Both these work items are tracked by spec issue 106.)
1483 pub fn parse_old_attribute_specification_opt(&mut self) -> S::R {
1484 if self.peek_token_kind() == TokenKind::LessThanLessThan {
1485 let (left, items, right) =
1486 self.parse_double_angled_comma_list_allow_trailing(|x: &mut Self| {
1487 x.parse_old_attribute()
1489 S!(make_old_attribute_specification, self, left, items, right)
1491 S!(make_missing, self, self.pos())
1495 fn parse_file_attribute_specification_opt(&mut self) -> S::R {
1496 if self.peek_token_kind() == TokenKind::LessThanLessThan {
1497 let left = self.assert_token(TokenKind::LessThanLessThan);
1498 let keyword = self.assert_token(TokenKind::File);
1499 let colon = self.require_colon();
1500 let (items, _) = self.parse_comma_list_allow_trailing(
1501 TokenKind::GreaterThanGreaterThan,
1502 Errors::expected_user_attribute,
1503 |x: &mut Self| x.parse_old_attribute(),
1505 let right = self.require_token(TokenKind::GreaterThanGreaterThan, Errors::error1029);
1507 make_file_attribute_specification,
1516 S!(make_missing, self, self.pos())
1520 fn parse_return_type_hint_opt(&mut self) -> (S::R, S::R) {
1521 let token_kind = self.peek_token_kind();
1522 if token_kind == TokenKind::Colon {
1523 let token = self.next_token();
1524 let colon_token = S!(make_token, self, token);
1526 self.with_type_parser(|p: &mut TypeParser<'a, S, T>| p.parse_return_type());
1527 (colon_token, return_type)
1529 let missing1 = S!(make_missing, self, self.pos());
1530 let missing2 = S!(make_missing, self, self.pos());
1531 (missing1, missing2)
1535 pub fn parse_parameter_list_opt(&mut self) -> (S::R, S::R, S::R) {
1537 // TODO: The specification is wrong in several respects concerning
1538 // variadic parameters. Variadic parameters are permitted to have a
1539 // type and name but this is not mentioned in the spec. And variadic
1540 // parameters are not mentioned at all in the grammar for constructor
1541 // parameter lists. (This is tracked by spec issue 107.)
1544 // variadic-parameter
1545 // parameter-declaration-list
1546 // parameter-declaration-list ,
1547 // parameter-declaration-list , variadic-parameter
1549 // parameter-declaration-list:
1550 // parameter-declaration
1551 // parameter-declaration-list , parameter-declaration
1553 // variadic-parameter:
1555 // attribute-specification-opt visiblity-modifier-opt type-specifier \
1556 // ... variable-name
1558 // This function parses the parens as well.
1559 // ERROR RECOVERY: We allow variadic parameters in all positions; a later
1560 // pass gives an error if a variadic parameter is in an incorrect position
1561 // or followed by a trailing comma, or if the parameter has a
1563 self.parse_parenthesized_comma_list_opt_allow_trailing(|x: &mut Self| x.parse_parameter())
1566 fn parse_parameter(&mut self) -> S::R {
1567 let mut parser1 = self.clone();
1568 let token = parser1.next_token();
1569 match token.kind() {
1570 TokenKind::DotDotDot => {
1571 let next_kind = parser1.peek_token_kind();
1572 if next_kind == TokenKind::Variable {
1573 self.parse_parameter_declaration()
1575 let missing1 = S!(make_missing, parser1, self.pos());
1576 let missing2 = S!(make_missing, parser1, self.pos());
1577 self.continue_from(parser1);
1578 let token = S!(make_token, self, token);
1579 S!(make_variadic_parameter, self, missing1, missing2, token)
1582 _ => self.parse_parameter_declaration(),
1586 fn parse_parameter_declaration(&mut self) -> S::R {
1589 // TODO: Add call-convention-opt to the specification.
1590 // (This work is tracked by task T22582676.)
1592 // TODO: Update grammar for inout parameters.
1593 // (This work is tracked by task T22582715.)
1595 // parameter-declaration:
1596 // attribute-specification-opt \
1597 // call-convention-opt \
1598 // type-specifier variable-name \
1599 // default-argument-specifier-opt
1602 // In strict mode, we require a type specifier. This error is not caught
1603 // at parse time but rather by a later pass.
1604 // Visibility modifiers are only legal in constructor parameter
1605 // lists; we give an error in a later pass.
1606 // Variadic params cannot be declared inout; we permit that here but
1607 // give an error in a later pass.
1608 // Variadic params and inout params cannot have default values; these
1609 // errors are also reported in a later pass.
1610 let attrs = self.parse_attribute_specification_opt();
1611 let visibility = self.parse_visibility_modifier_opt();
1612 let callconv = self.parse_call_convention_opt();
1613 let token = self.peek_token();
1614 let type_specifier = match token.kind() {
1615 TokenKind::Variable | TokenKind::DotDotDot | TokenKind::Ampersand => {
1616 S!(make_missing, self, self.pos())
1619 self.parse_type_specifier(/* allow_var = */ false, /* allow_attr */ false)
1622 let name = self.parse_decorated_variable_opt();
1623 let default = self.parse_simple_initializer_opt();
1625 make_parameter_declaration,
1636 fn parse_decorated_variable_opt(&mut self) -> S::R {
1637 match self.peek_token_kind() {
1638 TokenKind::DotDotDot | TokenKind::Ampersand => self.parse_decorated_variable(),
1639 _ => self.require_variable(),
1643 // TODO: This is wrong. The variable here is not anexpression* that has
1644 // an optional decoration on it. It's a declaration. We shouldn't be using the
1645 // same data structure for a decorated expression as a declaration; one
1646 // is ause* and the other is a *definition*.
1647 fn parse_decorated_variable(&mut self) -> S::R {
1649 // Detection of (variadic, byRef) inout params happens in post-parsing.
1650 // Although a parameter can have at most one variadic/reference decorator,
1651 // we deliberately allow multiple decorators in the initial parse and produce
1652 // an error in a later pass.
1653 let decorator = self.fetch_token();
1654 let variable = match self.peek_token_kind() {
1655 TokenKind::DotDotDot | TokenKind::Ampersand => self.parse_decorated_variable(),
1656 _ => self.require_variable(),
1658 S!(make_decorated_expression, self, decorator, variable)
1661 fn parse_visibility_modifier_opt(&mut self) -> S::R {
1662 let token_kind = self.peek_token_kind();
1664 TokenKind::Public | TokenKind::Protected | TokenKind::Private => {
1665 let token = self.next_token();
1666 S!(make_token, self, token)
1668 _ => S!(make_missing, self, self.pos()),
1674 // TODO: Add this to the specification.
1675 // (This work is tracked by task T22582676.)
1679 fn parse_call_convention_opt(&mut self) -> S::R {
1680 let token_kind = self.peek_token_kind();
1682 TokenKind::Inout => {
1683 let token = self.next_token();
1684 S!(make_token, self, token)
1686 _ => S!(make_missing, self, self.pos()),
1691 // default-argument-specifier:
1692 // = const-expression
1694 // constant-initializer:
1695 // = const-expression
1696 fn parse_simple_initializer_opt(&mut self) -> S::R {
1697 let token_kind = self.peek_token_kind();
1699 TokenKind::Equal => {
1700 let token = self.next_token();
1701 // TODO: Detect if expression is not const
1702 let token = S!(make_token, self, token);
1703 let default_value = self.parse_expression();
1704 S!(make_simple_initializer, self, token, default_value)
1706 _ => S!(make_missing, self, self.pos()),
1710 pub fn parse_function_declaration(&mut self, attribute_specification: S::R) -> S::R {
1711 let modifiers = self.parse_modifiers();
1713 self.parse_function_declaration_header(modifiers, /* is_methodish =*/ false);
1714 let body = self.parse_compound_statement();
1716 make_function_declaration,
1718 attribute_specification,
1724 fn parse_constraint_operator(&mut self) -> S::R {
1725 // TODO: Put this in the specification
1726 // (This work is tracked by spec issue 100.)
1727 // constraint-operator:
1731 let token_kind = self.peek_token_kind();
1733 TokenKind::Equal | TokenKind::As | TokenKind::Super => {
1734 let token = self.next_token();
1735 S!(make_token, self, token)
1738 // ERROR RECOVERY: don't eat the offending token.
1739 // TODO: Give parse error
1741 S!(make_missing, self, self.pos())
1746 fn parse_where_constraint(&mut self) -> S::R {
1747 // TODO: Put this in the specification
1748 // (This work is tracked by spec issue 100.)
1750 // type-specifier constraint-operator type-specifier
1752 self.parse_type_specifier(/* allow_var = */ false, /* allow_attr = */ true);
1753 let op = self.parse_constraint_operator();
1755 self.parse_type_specifier(/* allow_var = */ false, /* allow_attr = */ true);
1756 S!(make_where_constraint, self, left, op, right)
1759 fn parse_where_constraint_list_item(&mut self) -> Option<S::R> {
1760 match self.peek_token_kind() {
1761 TokenKind::Semicolon | TokenKind::LeftBrace => None,
1763 let where_constraint = self.parse_where_constraint();
1764 let comma = self.optional_token(TokenKind::Comma);
1765 let result = S!(make_list_item, self, where_constraint, comma);
1771 fn parse_where_clause(&mut self) -> S::R {
1772 // TODO: Add this to the specification
1773 // (This work is tracked by spec issue 100.)
1775 // where constraint-list
1779 // constraint-list , constraint
1780 let keyword = self.assert_token(TokenKind::Where);
1782 self.parse_list_until_none(|x: &mut Self| x.parse_where_constraint_list_item());
1783 S!(make_where_clause, self, keyword, constraints)
1786 fn parse_where_clause_opt(&mut self) -> S::R {
1787 if self.peek_token_kind() != TokenKind::Where {
1788 S!(make_missing, self, self.pos())
1790 self.parse_where_clause()
1794 fn parse_function_declaration_header(&mut self, modifiers: S::R, is_methodish: bool) -> S::R {
1796 // function-definition-header:
1797 // attribute-specification-opt async-opt coroutine-opt function name /
1798 // generic-type-parameter-list-opt ( parameter-list-opt ) : /
1799 // return-type where-clause-opt
1800 // TODO: The spec does not specify "where" clauses. Add them.
1801 // (This work is tracked by spec issue 100.)
1803 // In strict mode, we require a type specifier. This error is not caught
1804 // at parse time but rather by a later pass.
1805 let function_token = self.require_function();
1806 let label = self.parse_function_label_opt(is_methodish);
1807 let generic_type_parameter_list = self.parse_generic_type_parameter_list_opt();
1808 let (left_paren_token, parameter_list, right_paren_token) = self.parse_parameter_list_opt();
1809 let (colon_token, return_type) = self.parse_return_type_hint_opt();
1810 let where_clause = self.parse_where_clause_opt();
1812 make_function_declaration_header,
1817 generic_type_parameter_list,
1827 // A function label is either a function name or a __construct label.
1828 fn parse_function_label_opt(&mut self, is_methodish: bool) -> S::R {
1829 let report_error = |x: &mut Self, token: S::Token| {
1830 x.with_error(Errors::error1044);
1831 let token = S!(make_token, x, token);
1832 S!(make_error, x, token)
1834 let token_kind = self.peek_token_kind();
1836 TokenKind::Name | TokenKind::Construct => {
1837 let token = self.next_token();
1838 S!(make_token, self, token)
1840 TokenKind::LeftParen => {
1841 // It turns out, it was just a verbose lambda; YOLO PHP
1842 S!(make_missing, self, self.pos())
1844 TokenKind::Isset | TokenKind::Unset | TokenKind::Empty => {
1845 // We need to parse those as names as they are defined in hhi
1846 let token = self.next_token_as_name();
1847 S!(make_token, self, token)
1850 let token = if is_methodish {
1851 self.next_token_as_name()
1853 self.next_token_non_reserved_as_name()
1855 if token.kind() == TokenKind::Name {
1856 S!(make_token, self, token)
1858 // ERROR RECOVERY: Eat the offending token.
1859 report_error(self, token)
1865 fn parse_old_attribute(&mut self) -> S::R {
1866 self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| p.parse_constructor_call())
1869 pub fn parse_attribute_specification_opt(&mut self) -> S::R {
1870 match self.peek_token_kind() {
1871 TokenKind::At if self.env.allow_new_attribute_syntax => {
1872 self.parse_new_attribute_specification_opt()
1874 TokenKind::LessThanLessThan => self.parse_old_attribute_specification_opt(),
1875 _ => S!(make_missing, self, self.pos()),
1879 fn parse_new_attribute_specification_opt(&mut self) -> S::R {
1880 let attributes = self.parse_list_while(
1881 |p: &mut Self| p.parse_new_attribute(),
1882 |p: &Self| p.peek_token_kind() == TokenKind::At,
1884 S!(make_attribute_specification, self, attributes)
1887 fn parse_new_attribute(&mut self) -> S::R {
1888 let at = self.assert_token(TokenKind::At);
1889 let token = self.peek_token();
1890 let constructor_call = match token.kind() {
1891 TokenKind::Name => self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| {
1892 p.parse_constructor_call()
1895 self.with_error(Errors::expected_user_attribute);
1896 S!(make_missing, self, self.pos())
1899 S!(make_attribute, self, at, constructor_call)
1902 // Parses modifiers and passes them into the parse methods for the
1903 // respective class body element.
1904 fn parse_methodish_or_property_or_const_or_type_const(&mut self) -> S::R {
1905 let mut parser1 = self.clone();
1906 let modifiers = parser1.parse_modifiers();
1907 let kind0 = parser1.peek_token_kind_with_lookahead(0);
1908 let kind1 = parser1.peek_token_kind_with_lookahead(1);
1909 let kind2 = parser1.peek_token_kind_with_lookahead(2);
1910 match (kind0, kind1, kind2) {
1911 (TokenKind::Const, TokenKind::Type, TokenKind::Semicolon) => {
1912 self.continue_from(parser1);
1913 let const_ = self.assert_token(TokenKind::Const);
1914 self.parse_const_declaration(modifiers, const_)
1916 (TokenKind::Const, TokenKind::Type, _) if kind2 != TokenKind::Equal => {
1917 let attributes = S!(make_missing, self, self.pos());
1918 let modifiers = self.parse_modifiers();
1919 let const_ = self.assert_token(TokenKind::Const);
1920 self.parse_type_const_declaration(attributes, modifiers, const_)
1922 (TokenKind::Const, _, _) => {
1923 self.continue_from(parser1);
1924 let const_ = self.assert_token(TokenKind::Const);
1925 self.parse_const_declaration(modifiers, const_)
1928 let missing = S!(make_missing, self, self.pos());
1929 self.parse_methodish_or_property(missing)
1935 // method-declaration:
1936 // attribute-spec-opt method-modifiers function-definition
1937 // attribute-spec-opt method-modifiers function-definition-header ;
1938 // method-modifiers:
1940 // method-modifiers method-modifier
1942 // visibility-modifier (i.e. private, public, protected)
1946 fn parse_methodish(&mut self, attribute_spec: S::R, modifiers: S::R) -> S::R {
1948 self.parse_function_declaration_header(modifiers, /* is_methodish:*/ true);
1949 let token_kind = self.peek_token_kind();
1951 TokenKind::LeftBrace => {
1952 let body = self.parse_compound_statement();
1953 let missing = S!(make_missing, self, self.pos());
1955 make_methodish_declaration,
1963 TokenKind::Semicolon => {
1964 let pos = self.pos();
1965 let token = self.next_token();
1966 let missing = S!(make_missing, self, pos);
1967 let semicolon = S!(make_token, self, token);
1969 make_methodish_declaration,
1977 TokenKind::Equal => {
1978 let equal = self.assert_token(TokenKind::Equal);
1979 let qualifier = self.parse_qualified_name_type();
1980 let cc_token = self.require_coloncolon();
1981 let name = self.require_token_one_of(
1982 &[TokenKind::Name, TokenKind::Construct],
1986 make_scope_resolution_expression,
1992 let semi = self.require_semicolon();
1994 make_methodish_trait_resolution,
2004 // ERROR RECOVERY: We expected either a block or a semicolon; we got
2005 // neither. Use the offending token as the body of the method.
2006 // TODO: Is this the right error recovery?
2007 let pos = self.pos();
2008 let token = self.next_token();
2009 self.with_error(Errors::error1041);
2010 let token = S!(make_token, self, token);
2011 let error = S!(make_error, self, token);
2012 let missing = S!(make_missing, self, pos);
2014 make_methodish_declaration,
2024 fn parse_modifiers(&mut self) -> S::R {
2025 let mut items = vec![];
2027 let token_kind = self.peek_token_kind();
2032 | TokenKind::Protected
2033 | TokenKind::Private
2035 | TokenKind::Coroutine
2036 | TokenKind::Final => {
2037 let token = self.next_token();
2038 let item = S!(make_token, self, token);
2044 S!(make_list, self, items, self.pos())
2047 fn parse_enum_or_classish_or_function_declaration(&mut self) -> S::R {
2048 // An enum, type alias, function, interface, trait or class may all
2049 // begin with an attribute.
2050 let mut parser1 = self.clone();
2051 let attribute_specification = parser1.parse_attribute_specification_opt();
2053 let mut parser2 = parser1.clone();
2054 let token = parser2.next_token();
2055 match token.kind() {
2056 TokenKind::Enum => {
2057 self.continue_from(parser1);
2058 self.parse_enum_declaration(attribute_specification)
2060 TokenKind::Type | TokenKind::Newtype => {
2061 self.continue_from(parser1);
2063 self.parse_alias_declaration(attribute_specification)
2065 TokenKind::Async | TokenKind::Coroutine | TokenKind::Function => {
2066 if attribute_specification.is_missing() {
2067 // if attribute section is missing - it might be either
2068 // function declaration or expression statement containing
2069 // anonymous function - use statement parser to determine in which case
2070 // we are currently in
2071 self.with_statement_parser(|p: &mut StatementParser<'a, S, T>| {
2072 p.parse_possible_php_function(/* toplevel=*/ true)
2075 self.continue_from(parser1);
2076 self.parse_function_declaration(attribute_specification)
2081 | TokenKind::Interface
2083 | TokenKind::Class => {
2084 self.continue_from(parser1);
2085 self.parse_classish_declaration(attribute_specification)
2088 // ERROR RECOVERY: we encountered an unexpected token, raise an error and continue
2089 // TODO: This is wrong; we have lost the attribute specification
2091 self.continue_from(parser2);
2092 self.with_error(Errors::error1057(self.token_text(&token)));
2093 let token = S!(make_token, self, token);
2094 S!(make_error, self, token)
2099 fn parse_classish_element(&mut self) -> S::R {
2100 // We need to identify an element of a class, trait, etc. Possibilities
2103 // // constant-declaration:
2105 // abstract const T $x ;
2106 // public const T $x = v ; // PHP7 only
2108 // // type-constant-declaration
2109 // const type T = X;
2110 // abstract const type T;
2112 // // property-declaration:
2113 // public/private/protected/static T $x;
2114 // TODO: We may wish to parse "T $x" and give an error indicating
2115 // TODO: that we were expecting either const or public.
2116 // Note that a visibility modifier is required; static is optional;
2117 // any order is allowed.
2119 // // method-declaration
2120 // <<attr>> public/private/protected/abstract/final/static async function
2121 // Note that a modifier is required, the attr and async are optional.
2122 // TODO: Hack requires a visibility modifier, unless "static" is supplied,
2123 // TODO: in which case the method is considered to be public. Is this
2124 // TODO: desired? Resolve this disagreement with the spec.
2126 // // constructor-declaration
2127 // <<attr>> public/private/protected/abstract/final function __construct
2128 // Note that we allow static constructors in this parser; we produce an
2129 // error in the post-parse error detection pass.
2132 // require extends qualified-name
2133 // require implements qualified-name
2135 // // XHP class attribute declaration
2138 // // XHP category declaration
2141 // // XHP children declaration
2144 // // Pocket Universe Enumeration
2145 // final? enum id { ... (pocket-field ;) * }
2146 match self.peek_token_kind() {
2147 TokenKind::Children => self.parse_xhp_children_declaration(),
2148 TokenKind::Category => self.parse_xhp_category_declaration(),
2149 TokenKind::Use => self.parse_trait_use(),
2151 | TokenKind::Abstract
2153 | TokenKind::Protected
2154 | TokenKind::Private
2155 | TokenKind::Static => self.parse_methodish_or_property_or_const_or_type_const(),
2156 TokenKind::Enum => self.parse_class_enum(false),
2157 TokenKind::Final => {
2158 match self.peek_token_kind_with_lookahead(1) {
2159 TokenKind::Enum => self.parse_class_enum(/* final:*/ true),
2161 // Parse class methods, constructors, properties
2162 // or type constants.
2163 let attr = self.parse_attribute_specification_opt();
2164 self.parse_methodish_or_property_or_type_constant(attr)
2168 TokenKind::Async | TokenKind::LessThanLessThan => {
2169 // Parse methods, constructors, properties, or type constants.
2170 let attr = self.parse_attribute_specification_opt();
2171 self.parse_methodish_or_property_or_type_constant(attr)
2173 TokenKind::At if self.env.allow_new_attribute_syntax => {
2174 let attr = self.parse_attribute_specification_opt();
2175 self.parse_methodish_or_property_or_type_constant(attr)
2177 TokenKind::Require => {
2178 // We give an error if these are found where they should not be,
2180 self.parse_require_clause()
2182 TokenKind::Attribute => self.parse_xhp_class_attribute_declaration(),
2183 TokenKind::Function => {
2185 // Hack requires that a function inside a class be marked
2186 // with a visibility modifier, but PHP does not have this requirement.
2187 // We accept the lack of a modifier here, and produce an error in
2189 let missing1 = S!(make_missing, self, self.pos());
2190 let missing2 = S!(make_missing, self, self.pos());
2191 self.parse_methodish(missing1, missing2)
2193 kind if self.expects(kind) => S!(make_missing, self, self.pos()),
2195 // If this is a property declaration which is missing its visibility
2196 // modifier, accept it here, but emit an error in a later pass.
2197 let mut parser1 = self.clone();
2198 let missing1 = S!(make_missing, parser1, self.pos());
2199 let missing2 = S!(make_missing, parser1, self.pos());
2200 let property = parser1.parse_property_declaration(missing1, missing2);
2201 if self.errors.len() == parser1.errors.len() {
2202 self.continue_from(parser1);
2205 // TODO ERROR RECOVERY could be improved here.
2206 let token = self.fetch_token();
2207 self.with_error(Errors::error1033);
2208 S!(make_error, self, token)
2209 // Parser does not detect the error where non-static instance variables
2210 // or methods are within abstract final classes in its first pass, but
2211 // instead detects it in its second pass.
2217 fn parse_generic_type_parameter_list_opt(&mut self) -> S::R {
2218 match self.peek_token_kind_with_possible_attributized_type_list() {
2219 TokenKind::LessThan => self.with_type_parser(|p: &mut TypeParser<'a, S, T>| {
2220 p.parse_generic_type_parameter_list()
2222 _ => S!(make_missing, self, self.pos()),
2226 fn parse_type_constraint_opt(&mut self) -> S::R {
2227 self.with_type_parser(|p: &mut TypeParser<'a, S, T>| p.parse_type_constraint_opt())
2230 fn parse_alias_declaration(&mut self, attr: S::R) -> S::R {
2232 // alias-declaration:
2233 // attribute-spec-opt type name
2234 // generic-type-parameter-list-opt = type-specifier ;
2235 // attribute-spec-opt newtype name
2236 // generic-type-parameter-list-opt type-constraint-opt
2237 // = type-specifier ;
2238 let token = self.fetch_token();
2239 // Not `require_name` but `require_name_allow_non_reserved`, because the parser
2240 // must allow keywords in the place of identifiers; at least to parse .hhi
2242 let name = self.require_name_allow_non_reserved();
2243 let generic = self.parse_generic_type_parameter_list_opt();
2244 let constr = self.parse_type_constraint_opt();
2245 let equal = self.require_equal();
2246 let ty = self.parse_type_specifier(false /* allow_var */, true /* allow_attr */);
2247 let semi = self.require_semicolon();
2249 make_alias_declaration,
2262 fn parse_enumerator(&mut self) -> S::R {
2265 // enumerator-constant = constant-expression ;
2266 // enumerator-constant:
2269 // TODO: Add an error to a later pass that determines the value is
2272 // TODO: We must allow TRUE to be a legal enum member name; here we allow
2273 // any keyword. Consider making this more strict.
2274 let name = self.require_name_allow_all_keywords();
2275 let equal = self.require_equal();
2276 let value = self.parse_expression();
2277 let semicolon = self.require_semicolon();
2278 S!(make_enumerator, self, name, equal, value, semicolon)
2281 fn parse_inclusion_directive(&mut self) -> S::R {
2283 // inclusion-directive:
2284 // require-multiple-directive
2285 // require-once-directive
2287 // require-multiple-directive:
2288 // require include-filename ;
2290 // include-filename:
2293 // require-once-directive:
2294 // require_once include-filename ;
2296 // In non-strict mode we allow an inclusion directive (without semi) to be
2297 // used as an expression. It is therefore easier to actually parse this as:
2299 // inclusion-directive:
2300 // inclusion-expression ;
2302 // inclusion-expression:
2303 // require include-filename
2304 // require_once include-filename
2305 let expr = self.parse_expression();
2306 let semi = self.require_semicolon();
2307 S!(make_inclusion_directive, self, expr, semi)
2310 fn parse_declaration(&mut self) -> S::R {
2311 self.expect_in_new_scope(ExpectedTokens::Classish);
2312 let mut parser1 = self.clone();
2313 let token = parser1.next_token();
2315 match token.kind() {
2317 | TokenKind::Include_once
2318 | TokenKind::Require
2319 | TokenKind::Require_once => self.parse_inclusion_directive(),
2320 TokenKind::Type | TokenKind::Newtype
2322 let kind = parser1.peek_token_kind();
2323 kind == TokenKind::Name || kind == TokenKind::Classname
2326 let missing = S!(make_missing, self, self.pos());
2327 self.parse_alias_declaration(missing)
2329 TokenKind::Enum => {
2330 let missing = S!(make_missing, self, self.pos());
2331 self.parse_enum_declaration(missing)
2333 TokenKind::RecordDec => {
2334 let missing = S!(make_missing, self, self.pos());
2335 self.parse_record_declaration(missing)
2337 // The keyword namespace before a name should be parsed as
2338 // "the current namespace we are in", essentially a no op.
2340 // namespace\f1(); should be parsed as a call to the function f1 in
2341 // the current namespace.
2342 TokenKind::Namespace if parser1.peek_token_kind() == TokenKind::Backslash => self
2343 .with_statement_parser(|p: &mut StatementParser<'a, S, T>| p.parse_statement()),
2344 TokenKind::Namespace => self.parse_namespace_declaration(),
2345 TokenKind::Use => self.parse_namespace_use_declaration(),
2346 TokenKind::Trait | TokenKind::Interface | TokenKind::Class => {
2347 let missing = S!(make_missing, self, self.pos());
2348 self.parse_classish_declaration(missing)
2350 TokenKind::Abstract | TokenKind::Final => {
2351 let missing = S!(make_missing, self, self.pos());
2352 match parser1.peek_token_kind() {
2353 TokenKind::RecordDec => self.parse_record_declaration(missing),
2354 _ => self.parse_classish_declaration(missing),
2357 TokenKind::Async | TokenKind::Coroutine | TokenKind::Function => self
2358 .with_statement_parser(|p: &mut StatementParser<'a, S, T>| {
2359 p.parse_possible_php_function(true)
2361 TokenKind::At if self.env.allow_new_attribute_syntax => {
2362 self.parse_enum_or_classish_or_function_declaration()
2364 TokenKind::LessThanLessThan => match parser1.peek_token_kind() {
2366 if parser1.peek_token_kind_with_lookahead(1) == TokenKind::Colon =>
2368 self.parse_file_attribute_specification_opt()
2370 _ => self.parse_enum_or_classish_or_function_declaration(),
2372 // TODO figure out what global const differs from class const
2373 TokenKind::Const => {
2374 let missing1 = S!(make_missing, parser1, self.pos());
2375 self.continue_from(parser1);
2376 let token = S!(make_token, self, token);
2377 self.parse_const_declaration(missing1, token)
2379 // TODO: What if it's not a legal statement? Do we still make progress here?
2381 .with_statement_parser(|p: &mut StatementParser<'a, S, T>| p.parse_statement()),
2384 self.pop_scope(ExpectedTokens::Classish);
2388 fn parse_pocket_mapping(&mut self) -> S::R {
2390 // pocket-mapping ::=
2391 // | 'type' identifier '=' type-expression
2392 // | identifier '=' expression
2393 match self.peek_token_kind() {
2394 TokenKind::Type => {
2395 let typ = self.require_token(TokenKind::Type, Errors::type_keyword);
2396 let tyname = self.require_name();
2397 let equal = self.require_equal();
2398 let ty = self.parse_type_specifier(false, true);
2400 make_pocket_mapping_type_declaration,
2408 TokenKind::Name => {
2409 let id = self.require_name();
2410 let equal = self.require_equal();
2411 let simple_init = self.parse_expression();
2412 let sc_init = S!(make_simple_initializer, self, equal, simple_init);
2413 S!(make_pocket_mapping_id_declaration, self, id, sc_init)
2416 self.with_error(Errors::pocket_universe_invalid_field);
2417 S!(make_missing, self, self.pos())
2422 fn parse_pocket_field(&mut self) -> S::R {
2426 // | enum-member '(' (pocket-mapping ',')')' ;
2427 // | 'case' type-expression identifier ;
2428 // | 'case' 'type' identifier ;
2430 // enum-member ::= ':@' name
2431 match self.peek_token_kind() {
2432 TokenKind::ColonAt => {
2433 let glyph = self.assert_token(TokenKind::ColonAt);
2434 let enum_name = self.require_name();
2435 match self.peek_token_kind() {
2436 TokenKind::LeftParen => {
2437 let (left_paren, mappings, right_paren) =
2438 self.parse_parenthesized_comma_list(|x| x.parse_pocket_mapping());
2439 let semi = self.require_semicolon();
2441 make_pocket_atom_mapping_declaration,
2452 let missing_left = S!(make_missing, self, self.pos());
2453 let missing_mappings = S!(make_missing, self, self.pos());
2454 let missing_right = S!(make_missing, self, self.pos());
2455 let semi = self.require_semicolon();
2457 make_pocket_atom_mapping_declaration,
2469 TokenKind::Case => {
2470 let case_tok = self.assert_token(TokenKind::Case);
2471 match self.peek_token_kind() {
2472 TokenKind::Type => {
2473 let type_tok = self.assert_token(TokenKind::Type);
2474 let name = self.require_name();
2475 let semi = self.require_semicolon();
2477 make_pocket_field_type_declaration,
2486 let ty = self.parse_type_specifier(false, true);
2487 let name = self.require_name();
2488 let semi = self.require_semicolon();
2490 make_pocket_field_type_expr_declaration,
2501 self.with_error(Errors::pocket_universe_invalid_field);
2502 S!(make_missing, self, self.pos())
2507 fn parse_pocket_fields_opt(&mut self) -> S::R {
2509 // pocket-field-list:
2511 // pocket-field-list pocket-field
2512 self.parse_terminated_list(|x| x.parse_pocket_field(), TokenKind::RightBrace)
2515 fn parse_class_enum(&mut self, final_: bool /* = false */) -> S::R {
2517 // 'final'? 'enum' identifier '{' pocket-field-list '}'
2519 // from parse_classish_declaration.. probably could do better
2521 let final_tok = if final_ {
2522 self.require_token(TokenKind::Final, Errors::pocket_universe_final_expected)
2524 S!(make_missing, self, self.pos())
2527 let enum_tok = self.require_token(TokenKind::Enum, Errors::pocket_universe_enum_expected);
2528 let name = self.require_name();
2529 let (left_brace, pocket_fields, right_brace) =
2530 self.parse_braced_list(|x| x.parse_pocket_fields_opt());
2532 make_pocket_enum_declaration,
2543 pub fn parse_script(&mut self) -> S::R {
2544 // TODO(kasper): no_markup for ".hack" files
2545 let header = self.parse_leading_markup_section();
2546 let mut declarations = vec![];
2547 if let Some(x) = header {
2548 declarations.push(x)
2551 let token_kind = self.peek_token_kind();
2553 TokenKind::EndOfFile => {
2554 let token = self.next_token();
2555 let token = S!(make_token, self, token);
2556 let end_of_file = S!(make_end_of_file, self, token);
2557 declarations.push(end_of_file);
2560 _ => declarations.push(self.parse_declaration()),
2563 let declarations = S!(make_list, self, declarations, self.pos());
2564 let result = S!(make_script, self, declarations);
2565 assert_eq!(self.peek_token_kind(), TokenKind::EndOfFile);