mod tag;
mod test;
mod types;
use tag::{parse_long_tag, parse_tag};
use crate::{
kind::{LuaSyntaxKind, LuaTokenKind},
lexer::LuaDocLexerState,
parser::{LuaDocParser, MarkerEventContainer},
parser_error::LuaParseError,
};
pub fn parse_comment(p: &mut LuaDocParser) {
let m = p.mark(LuaSyntaxKind::Comment);
parse_docs(p);
m.complete(p);
}
fn parse_docs(p: &mut LuaDocParser) {
while p.current_token() != LuaTokenKind::TkEof {
match p.current_token() {
LuaTokenKind::TkDocStart => {
p.set_lexer_state(LuaDocLexerState::Tag);
p.bump();
parse_tag(p);
}
LuaTokenKind::TkDocLongStart => {
p.set_lexer_state(LuaDocLexerState::Tag);
p.bump();
parse_long_tag(p);
}
LuaTokenKind::TkNormalStart => {
p.set_lexer_state(LuaDocLexerState::NormalDescription);
let mut m = p.mark(LuaSyntaxKind::DocDescription);
p.bump();
if_token_bump(p, LuaTokenKind::TkWhitespace);
if matches!(
p.current_token(),
LuaTokenKind::TkDocRegion | LuaTokenKind::TkDocEndRegion
) {
m.undo(p);
p.bump();
m = p.mark(LuaSyntaxKind::DocDescription);
}
while let LuaTokenKind::TkDocDetail
| LuaTokenKind::TkEndOfLine
| LuaTokenKind::TkWhitespace
| LuaTokenKind::TkDocContinue
| LuaTokenKind::TkNormalStart = p.current_token()
{
p.bump();
}
m.complete(p);
}
LuaTokenKind::TkLongCommentStart => {
p.set_lexer_state(LuaDocLexerState::LongDescription);
p.bump();
parse_description(p);
}
LuaTokenKind::TKDocTriviaStart => {
p.bump();
}
_ => {
p.bump();
}
}
if let Some(reader) = &p.lexer.reader
&& !reader.is_eof()
&& !matches!(
p.current_token(),
LuaTokenKind::TkDocStart | LuaTokenKind::TkDocLongStart
)
{
p.bump_to_end();
continue;
}
p.set_lexer_state(LuaDocLexerState::Init);
}
}
fn parse_description(p: &mut LuaDocParser) {
let m = p.mark(LuaSyntaxKind::DocDescription);
while let LuaTokenKind::TkDocDetail
| LuaTokenKind::TkEndOfLine
| LuaTokenKind::TkWhitespace
| LuaTokenKind::TkDocContinue
| LuaTokenKind::TkNormalStart = p.current_token()
{
p.bump();
}
m.complete(p);
}
fn expect_token(p: &mut LuaDocParser, token: LuaTokenKind) -> Result<(), LuaParseError> {
if p.current_token() == token {
p.bump();
Ok(())
} else {
Err(LuaParseError::syntax_error_from(
&t!(
"expected %{token}, but get %{current}",
token = token,
current = p.current_token()
),
p.current_token_range(),
))
}
}
fn if_token_bump(p: &mut LuaDocParser, token: LuaTokenKind) -> bool {
if p.current_token() == token {
p.bump();
true
} else {
false
}
}