df_ls_syntax_analysis 0.3.0-rc.1

A language server for Dwarf Fortress RAW files
Documentation
#![cfg(debug_assertions)]

use df_ls_lexical_analysis::{Tree, TreeCursor};
use std::rc::Rc;

/// $builder should be of type `SyntaxTestBuilder`
#[macro_export]
macro_rules! test_tree_structure {
    // Check correctly deserialized tokens
    ( $builder:ident, [$( $t:ty => $x:expr ),* $(,)*]) => {
        {
            #[cfg(debug_assertions)]
            use pretty_assertions::assert_eq;

            // Run LexerTestBuilder first
            let ($builder, tree, source) = $builder.run_lexer_test_builder();
            let mut tree_cursor = tree.walk();
            // go to "header"
            tree_cursor.goto_first_child();
            // go to "comment"
            tree_cursor.goto_next_sibling();
            let mut diagnostic_info = DiagnosticsInfo::default();
            let mut token_group_counter = 1;
            $(
                $crate::test_utils::skip_comment(&mut tree_cursor, &tree, token_group_counter);

                // Test if next tokens are deserialized correctly and the same as expected.
                let given_value: $t = match $crate::TokenDeserialize::deserialize_tokens(&mut tree_cursor, &source, &mut diagnostic_info){
                    Ok(v) => *v,
                    Err(_err) => {
                        // log::error!("{:#?}", err); // Error is of type `()` so no need to print it.
                        let given_s_exp = tree.root_node().to_sexp(0);
                        log::info!("Given S-Expression:\n{}", given_s_exp);
                        panic!("Current token group #{}. Failed to deserialize token", token_group_counter);
                    }
                };
                assert_eq!(
                    $x,
                    given_value
                );

                token_group_counter += 1;
            )*
            // Suppress unused warning
            let _ = token_group_counter;

            // Run SyntaxTestBuilder
            $builder.run_test_with_custom_data(&false, diagnostic_info);
        }
    };
    // Check incorrectly deserialized tokens
    ( $builder:ident, [$( $t:ty =! ),* $(,)*]) => {
        {
            // Run LexerTestBuilder first
            let ($builder, tree, source) = $builder.run_lexer_test_builder();
            let mut tree_cursor = tree.walk();
            // go to "header"
            tree_cursor.goto_first_child();
            // go to "comment"
            tree_cursor.goto_next_sibling();
            let mut diagnostic_info = DiagnosticsInfo::default();
            let mut token_group_counter = 1;
            $(
                $crate::test_utils::skip_comment(&mut tree_cursor, &tree, token_group_counter);

                // Test if next tokens are deserialized correctly and the same as expected.
                let given_result: Result<Box<$t>, ()> = $crate::TokenDeserialize::deserialize_tokens(&mut tree_cursor, &source, &mut diagnostic_info);
                match given_result {
                    Ok(v) => {
                        let given_s_exp = tree.root_node().to_sexp(0);
                        log::info!("Given S-Expression:\n{}", given_s_exp);
                        log::error!("Value correctly deserialized: {:#?}", *v);
                        panic!(
                            "Current token group #{}. Was correctly deserialize token, \
                            Expected an deserialization error", token_group_counter
                        );
                    }
                    Err(_err) => {}
                }

                token_group_counter += 1;
            )*
            // Suppress unused warning
            let _ = token_group_counter;

            // Run SyntaxTestBuilder
            $builder.run_test_with_custom_data(&false, diagnostic_info);
        }
    };
}

pub fn skip_comment(tree_cursor: &mut TreeCursor, tree: &Rc<Tree>, token_group_counter: u32) {
    // Skip "comment"
    let node = tree_cursor.node();
    if &node.kind() == "comment" {
        // Go to next node (if it exists)
        if !tree_cursor.goto_next_sibling() {
            // Print S-Expression for debugging
            let given_s_exp = tree.root_node().to_sexp(0);
            log::info!("Given S-Expression:\n{}", given_s_exp);
            panic!(
                "Current token group #{}. The next token does not exist.",
                token_group_counter
            );
        }
    }
}