use ktrs_syntax::SyntaxKind::{self, *};
use super::parameters::{AnnotationParsingMode, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER};
use super::{COMMA_COLON_GT_SET, CONTEXT_PARAMETERS_FOLLOW_SET};
use crate::kt_tokens::{MODIFIER_KEYWORDS, RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS, TYPE_ARGUMENT_MODIFIER_KEYWORDS, TYPE_MODIFIER_KEYWORDS};
use crate::parsing::{Consumer, Parser};
use crate::token_set::TokenSet;
impl Parser {
pub(crate) fn parse_modifier_list(&mut self, no_modifiers_before: TokenSet) -> bool {
self.parse_modifier_list_3(None, no_modifiers_before, false)
}
pub(crate) fn parse_annotations_list(&mut self, no_modifiers_before: TokenSet) {
self.do_parse_modifier_list(
None,
TokenSet::EMPTY,
AnnotationParsingMode::Default,
no_modifiers_before,
false,
);
}
pub(crate) fn parse_modifier_list_3(
&mut self,
token_consumer: Option<&mut dyn Consumer<SyntaxKind>>,
no_modifiers_before: TokenSet,
local_declaration: bool,
) -> bool {
self.do_parse_modifier_list(
token_consumer,
MODIFIER_KEYWORDS,
AnnotationParsingMode::Default,
no_modifiers_before,
local_declaration,
)
}
pub(super) fn parse_function_type_value_parameter_modifier_list(&mut self) {
self.do_parse_modifier_list(
None,
RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS,
AnnotationParsingMode::NoAnnotationsNoContext,
NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER,
false,
);
}
pub(super) fn parse_type_modifier_list(&mut self) {
self.do_parse_modifier_list(
None,
TYPE_MODIFIER_KEYWORDS,
AnnotationParsingMode::TypeContext,
TokenSet::EMPTY,
false,
);
}
pub(super) fn parse_type_argument_modifier_list(&mut self) {
self.do_parse_modifier_list(
None,
TYPE_ARGUMENT_MODIFIER_KEYWORDS,
AnnotationParsingMode::NoAnnotationsNoContext,
COMMA_COLON_GT_SET,
false,
);
}
fn do_parse_modifier_list_body(
&mut self,
mut token_consumer: Option<&mut dyn Consumer<SyntaxKind>>,
modifier_keywords: TokenSet,
annotation_parsing_mode: AnnotationParsingMode,
no_modifiers_before: TokenSet,
local_declaration: bool,
) -> bool {
let mut empty = true;
while !self.eof() {
if self.at(AT) && annotation_parsing_mode.allow_annotations() {
let before_annotation_marker = self.mark();
let is_annotation_parsed = self.parse_annotation_or_list(annotation_parsing_mode);
if !is_annotation_parsed && !annotation_parsing_mode.with_significant_whitespace_before_arguments() {
before_annotation_marker.rollback_to(self);
let new_mode = if annotation_parsing_mode.allow_context_list() {
AnnotationParsingMode::WithSignificantWhitespaceBeforeArguments
} else {
AnnotationParsingMode::WithSignificantWhitespaceBeforeArgumentsNoContext
};
self.do_parse_modifier_list_body(
reborrow(&mut token_consumer),
modifier_keywords,
new_mode,
no_modifiers_before,
local_declaration,
);
empty = false;
break;
} else {
before_annotation_marker.drop(self);
}
} else if self.at(CONTEXT_KEYWORD)
&& annotation_parsing_mode.allow_context_list()
&& self.lookahead(1) == Some(LPAR)
{
let context_marker = self.mark();
if !self.parse_context_parameter_or_receiver_list(false) && local_declaration {
context_marker.rollback_to(self);
break;
} else {
context_marker.drop(self);
}
} else if self.try_parse_modifier(reborrow(&mut token_consumer),no_modifiers_before, modifier_keywords) {
} else {
break;
}
empty = false;
}
empty
}
fn do_parse_modifier_list(
&mut self,
token_consumer: Option<&mut dyn Consumer<SyntaxKind>>,
modifier_keywords: TokenSet,
annotation_parsing_mode: AnnotationParsingMode,
no_modifiers_before: TokenSet,
local_declaration: bool,
) -> bool {
let list = self.mark();
let empty = self.do_parse_modifier_list_body(
token_consumer,
modifier_keywords,
annotation_parsing_mode,
no_modifiers_before,
local_declaration,
);
if empty {
list.drop(self);
} else {
list.done(self, MODIFIER_LIST);
}
!empty
}
fn try_parse_modifier(
&mut self,
token_consumer: Option<&mut dyn Consumer<SyntaxKind>>,
no_modifiers_before: TokenSet,
modifier_keywords: TokenSet,
) -> bool {
let marker = self.mark();
if self.at_set(modifier_keywords) {
let lookahead = self.lookahead(1);
if self.at(FUN_KEYWORD) && lookahead != Some(INTERFACE_KEYWORD) {
marker.rollback_to(self);
return false;
}
if lookahead.is_some() && !no_modifiers_before.contains(lookahead) {
let tt = self.tt().expect("at_set matched a token");
if let Some(token_consumer) = token_consumer {
token_consumer.consume(tt);
}
self.advance(); marker.collapse(self, tt);
return true;
}
}
marker.rollback_to(self);
false
}
pub(super) fn parse_context_parameter_or_receiver_list(&mut self, in_function_type: bool) -> bool {
debug_assert!(self._at(CONTEXT_KEYWORD));
let value_parameter_or_type_ref_list = self.mark();
self.advance();
debug_assert!(self._at(LPAR));
let no_error;
if self.lookahead(1) == Some(RPAR) {
self.advance(); self.error("Empty context parameter list");
self.advance(); no_error = false;
} else {
no_error = self.value_parameter_loop(in_function_type, CONTEXT_PARAMETERS_FOLLOW_SET, &mut |p: &mut Parser| {
p.parse_value_parameter_or_type_ref(in_function_type)
});
}
value_parameter_or_type_ref_list.done(self, CONTEXT_PARAMETER_LIST);
no_error
}
fn parse_value_parameter_or_type_ref(&mut self, in_function_type: bool) -> bool {
if self.try_parse_value_parameter(true) {
return true;
}
let context_receiver = self.mark();
if !in_function_type && self.is_at_label_definition_or_missing_identifier() {
self.parse_label_definition();
}
self.parse_type_ref();
context_receiver.done(self, CONTEXT_RECEIVER);
in_function_type
}
}
fn reborrow<'a>(consumer: &'a mut Option<&mut dyn Consumer<SyntaxKind>>) -> Option<&'a mut dyn Consumer<SyntaxKind>> {
match consumer {
Some(consumer) => Some(&mut **consumer),
None => None,
}
}