use crate::language::Token;
use crate::parsers::cst::Parser;
use crate::parsers::SyntaxKind;
impl Parser<'_> {
pub(crate) fn parse_call_statement(&mut self) {
self.parsing_header = false;
self.builder.start_node(SyntaxKind::CallStatement.to_raw());
self.consume_whitespace();
self.consume_token();
self.consume_until_after(Token::Newline);
self.builder.finish_node(); }
pub(crate) fn parse_procedure_call(&mut self) {
self.parsing_header = false;
self.builder.start_node(SyntaxKind::CallStatement.to_raw());
self.consume_whitespace();
self.consume_until_after(Token::Newline);
self.builder.finish_node(); }
pub(crate) fn is_at_procedure_call(&self) -> bool {
if self.at_token(Token::Identifier) {
} else if self.at_keyword() {
if let Some(
Token::EndKeyword
| Token::ExitKeyword
| Token::LoopKeyword
| Token::NextKeyword
| Token::WendKeyword
| Token::ElseKeyword
| Token::ElseIfKeyword
| Token::CaseKeyword
| Token::IfKeyword
| Token::ThenKeyword
| Token::SelectKeyword
| Token::DoKeyword
| Token::WhileKeyword
| Token::UntilKeyword
| Token::ForKeyword
| Token::ToKeyword
| Token::StepKeyword
| Token::SubKeyword
| Token::FunctionKeyword
| Token::PropertyKeyword
| Token::WithKeyword
| Token::ReturnKeyword
| Token::ResumeKeyword,
) = self.current_token()
{
return false;
}
} else {
return false;
}
for (_text, token) in self.tokens.iter().skip(self.pos) {
match token {
Token::Newline | Token::EndOfLineComment | Token::RemComment => {
return true;
}
Token::EqualityOperator => {
return false;
}
Token::Identifier
| Token::LeftParenthesis
| Token::RightParenthesis
| Token::Comma
| Token::PeriodOperator
| Token::StringLiteral
| Token::IntegerLiteral
| Token::LongLiteral
| Token::SingleLiteral
| Token::DoubleLiteral => {
}
_ if token.is_keyword() => {
}
_ => {}
}
}
false
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn call_statement_simple() {
let source = "Call MySubroutine()\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_with_arguments() {
let source = "Call ProcessData(x, y, z)\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_preserves_whitespace() {
let source = "Call MyFunction ( arg1 , arg2 )\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_in_sub() {
let source = "Sub Main()\nCall DoSomething()\nEnd Sub\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_no_parentheses() {
let source = "Call MySubroutine\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn multiple_call_statements() {
let source = "Call First()\nCall Second()\nCall Third()\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_with_string_arguments() {
let source = "Call ShowMessage(\"Hello, World!\")\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn call_statement_with_complex_expressions() {
let source = "Call Calculate(x + y, z * 2, (a - b) / c)\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_no_arguments() {
let source = "InitializeRandomDNA\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_with_parentheses() {
let source = "DoSomething()\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_with_arguments_no_parentheses() {
let source = "MsgBox \"Hello\", vbInformation, \"Title\"\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_with_arguments_with_parentheses() {
let source = "ProcessData(x, y, z)\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn multiple_procedure_calls_in_sub() {
let source = "Sub Test()\nInitializeRandomDNA\nGetInitialSize\nGetInitialSpeed\nEnd Sub\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_preserves_whitespace() {
let source = "MySub arg1 , arg2\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn procedure_call_vs_assignment() {
let source = "x = 5\n";
let (cst_opt, _failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("../../../../snapshots/syntax/statements/objects/call");
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
}