parol-ls 4.4.0

Language server for parol parser generator
use super::super::comments::Comments;
use super::super::{
    context::{FormatterContext, context_for_scanner_directive, scanner_directive_indent},
    indent::Indent,
};
use super::helpers::{
    comment_opts_left, comment_opts_left_force_remove, format_comments_before_token,
    format_trailing_comment,
};
use super::last_token::LastToken;
use super::traits::Fmt;
use crate::parol_ls_grammar_trait::{ScannerDirectives, ScannerStateDirectives};

pub(super) fn format_scanner_directives_with_context(
    scanner_directives: &ScannerDirectives,
    context: &FormatterContext<'_>,
    comments: Comments,
) -> (String, Comments) {
    let base_indent = Indent::make_indent(context.policy().nesting_depth);
    match scanner_directives {
        ScannerDirectives::PercentLineUnderscoreCommentTokenLiteral(l) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &l.percent_line_underscore_comment,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (comment_str, comments) = l.token_literal.txt(context.policy(), comments);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                l.token_literal.get_last_token(),
                &comment_opts_left_force_remove(context.policy()),
            );
            (
                format!(
                    "{}{}{} {}{}",
                    comments_before_token,
                    indent,
                    l.percent_line_underscore_comment,
                    comment_str,
                    following_comment,
                ),
                comments,
            )
        }
        ScannerDirectives::PercentAllowUnderscoreUnmatched(a) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &a.percent_allow_underscore_unmatched,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                &a.percent_allow_underscore_unmatched,
                &comment_opts_left_force_remove(context.policy()),
            );
            (
                format!(
                    "{}{}{}{}",
                    comments_before_token,
                    indent,
                    a.percent_allow_underscore_unmatched,
                    following_comment
                ),
                comments,
            )
        }
        ScannerDirectives::PercentBlockUnderscoreCommentTokenLiteralTokenLiteral(b) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &b.percent_block_underscore_comment,
                &comment_opts_left(context.policy()),
            );
            let (str1, comments) = b.token_literal.txt(context.policy(), comments);
            let (str2, comments) = b.token_literal0.txt(context.policy(), comments);
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                b.token_literal0.get_last_token(),
                &comment_opts_left_force_remove(context.policy()),
            );
            (
                format!(
                    "{}{}{} {} {}{}",
                    comments_before_token,
                    indent,
                    b.percent_block_underscore_comment,
                    str1,
                    str2,
                    following_comment,
                ),
                comments,
            )
        }

        ScannerDirectives::PercentAutoUnderscoreNewlineUnderscoreOff(n) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &n.percent_auto_underscore_newline_underscore_off,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                &n.percent_auto_underscore_newline_underscore_off,
                &comment_opts_left_force_remove(context.policy()),
            );
            (
                format!(
                    "{}{}{}{}",
                    comments_before_token,
                    indent,
                    n.percent_auto_underscore_newline_underscore_off,
                    following_comment
                ),
                comments,
            )
        }

        ScannerDirectives::PercentAutoUnderscoreWsUnderscoreOff(w) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &w.percent_auto_underscore_ws_underscore_off,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                &w.percent_auto_underscore_ws_underscore_off,
                &comment_opts_left_force_remove(context.policy()),
            );
            (
                format!(
                    "{}{}{}{}",
                    comments_before_token,
                    indent,
                    w.percent_auto_underscore_ws_underscore_off,
                    following_comment
                ),
                comments,
            )
        }
        ScannerDirectives::PercentSkipIdentifierList(skip) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &skip.percent_skip,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                skip.get_last_token(),
                &comment_opts_left_force_remove(context.policy()),
            );
            let ident_list = skip
                .identifier_list
                .identifier_list_list
                .iter()
                .fold(
                    vec![
                        skip.identifier_list
                            .identifier
                            .identifier
                            .text()
                            .to_string(),
                    ],
                    |mut acc, i| {
                        acc.push(i.identifier.identifier.text().to_string());
                        acc
                    },
                )
                .join(", ");
            (
                format!(
                    "{}{}{} {}{}",
                    comments_before_token, indent, skip.percent_skip, ident_list, following_comment,
                ),
                comments,
            )
        }
        ScannerDirectives::PercentOnIdentifierListScannerStateDirectives(trans) => {
            let (comments_before_token, comments) = format_comments_before_token(
                comments,
                &trans.percent_on,
                &comment_opts_left(context.policy()),
            );
            let context = context_for_scanner_directive(context, &comments_before_token);
            let indent = scanner_directive_indent(&base_indent, &context);
            let (following_comment, comments) = format_trailing_comment(
                comments,
                trans.get_last_token(),
                &comment_opts_left_force_remove(context.policy()),
            );
            let ident_list = trans
                .identifier_list
                .identifier_list_list
                .iter()
                .fold(
                    vec![
                        trans
                            .identifier_list
                            .identifier
                            .identifier
                            .text()
                            .to_string(),
                    ],
                    |mut acc, i| {
                        acc.push(i.identifier.identifier.text().to_string());
                        acc
                    },
                )
                .join(", ");
            let (text, comments) = match &trans.scanner_state_directives {
                ScannerStateDirectives::PercentEnterIdentifier(
                    scanner_state_directives_percent_enter_identifier,
                ) => {
                    let (ident, comments) = scanner_state_directives_percent_enter_identifier
                        .identifier
                        .txt(context.policy(), comments);
                    (format!("%enter {ident}",), comments)
                }
                ScannerStateDirectives::PercentPushIdentifier(
                    scanner_state_directives_percent_push_identifier,
                ) => {
                    let (ident, comments) = scanner_state_directives_percent_push_identifier
                        .identifier
                        .txt(context.policy(), comments);
                    (format!("%push {ident}",), comments)
                }
                ScannerStateDirectives::PercentPop(_) => ("%pop".to_string(), comments),
            };
            (
                format!(
                    "{}{}{} {} {}{}",
                    comments_before_token,
                    indent,
                    trans.percent_on,
                    ident_list,
                    text,
                    following_comment
                ),
                comments,
            )
        }
    }
}