diff --git a/crates/beamtalk-cli/src/commands/test_stdlib.rs b/crates/beamtalk-cli/src/commands/test_stdlib.rs index 3ba4bf8c8..4fd493b06 100644 --- a/crates/beamtalk-cli/src/commands/test_stdlib.rs +++ b/crates/beamtalk-cli/src/commands/test_stdlib.rs @@ -177,7 +177,7 @@ pub(crate) fn compile_expression_to_core( .ok_or_else(|| "No expression found in parsed source".to_string())?; // Generate Core Erlang test module (no workspace bindings) - beamtalk_core::codegen::core_erlang::generate_test_expression(expr, module_name) + beamtalk_core::codegen::core_erlang::generate_test_expression(&expr.expression, module_name) .map_err(|e| format!("{e}")) } diff --git a/crates/beamtalk-compiler-port/src/main.rs b/crates/beamtalk-compiler-port/src/main.rs index a0933465d..c72b629e4 100644 --- a/crates/beamtalk-compiler-port/src/main.rs +++ b/crates/beamtalk-compiler-port/src/main.rs @@ -428,7 +428,12 @@ fn handle_compile_expression(request: &Map) -> Term { } // BT-780: Generate Core Erlang for all expressions (multi-statement support) - match beamtalk_core::erlang::generate_repl_expressions(&module.expressions, &module_name) { + let expressions: Vec<_> = module + .expressions + .iter() + .map(|s| s.expression.clone()) + .collect(); + match beamtalk_core::erlang::generate_repl_expressions(&expressions, &module_name) { Ok(code) => ok_response(&code, &warnings), Err(e) => error_response(&[format!("Code generation failed: {e}")]), } @@ -485,10 +490,12 @@ fn handle_inline_class_definition( let trailing_core_erlang = if module.expressions.is_empty() { None } else { - match beamtalk_core::erlang::generate_repl_expressions( - &module.expressions, - expr_module_name, - ) { + let trailing_exprs: Vec<_> = module + .expressions + .iter() + .map(|s| s.expression.clone()) + .collect(); + match beamtalk_core::erlang::generate_repl_expressions(&trailing_exprs, expr_module_name) { Ok(code) => Some(code), Err(e) => { return error_response(&[format!( diff --git a/crates/beamtalk-core/src/ast.rs b/crates/beamtalk-core/src/ast.rs index cafb11040..c479ab0be 100644 --- a/crates/beamtalk-core/src/ast.rs +++ b/crates/beamtalk-core/src/ast.rs @@ -34,7 +34,7 @@ //! classes: Vec::new(), //! method_definitions: Vec::new(), //! expressions: vec![ -//! Expression::Assignment { +//! ExpressionStatement::bare(Expression::Assignment { //! target: Box::new(Expression::Identifier(Identifier { //! name: "x".into(), //! span: Span::new(0, 1), @@ -53,10 +53,10 @@ //! span: Span::new(5, 10), //! }), //! span: Span::new(0, 10), -//! } +//! }) //! ], //! span: Span::new(0, 10), -//! leading_comments: Vec::new(), +//! file_leading_comments: Vec::new(), //! }; //! # assert_eq!(module.expressions.len(), 1); //! ``` @@ -96,23 +96,25 @@ pub struct Module { /// Standalone method definitions (Tonel-style `Class >> method => body`). pub method_definitions: Vec, /// Top-level expressions (scripts, REPL input). - pub expressions: Vec, + pub expressions: Vec, /// Source location spanning the entire module. pub span: Span, - /// Leading comments (module documentation). - pub leading_comments: Vec, + /// File-level leading comments (ADR 0044). + /// + /// Comments at the very start of the file, before any expressions or class definitions. + pub file_leading_comments: Vec, } impl Module { /// Creates a new module with the given expressions and span. #[must_use] - pub fn new(expressions: Vec, span: Span) -> Self { + pub fn new(expressions: Vec, span: Span) -> Self { Self { classes: Vec::new(), method_definitions: Vec::new(), expressions, span, - leading_comments: Vec::new(), + file_leading_comments: Vec::new(), } } @@ -124,23 +126,23 @@ impl Module { method_definitions: Vec::new(), expressions: Vec::new(), span, - leading_comments: Vec::new(), + file_leading_comments: Vec::new(), } } - /// Creates a new module with comments. + /// Creates a new module with file-level leading comments. #[must_use] pub fn with_comments( - expressions: Vec, + expressions: Vec, span: Span, - leading_comments: Vec, + file_leading_comments: Vec, ) -> Self { Self { classes: Vec::new(), method_definitions: Vec::new(), expressions, span, - leading_comments, + file_leading_comments, } } } @@ -215,8 +217,7 @@ impl CommentAttachment { /// /// Wraps an [`Expression`] with a [`CommentAttachment`] for preserving comments /// between statements. Statement-position fields (method bodies, block bodies, -/// module expressions) will migrate from `Vec` to -/// `Vec` in BT-974. +/// module expressions) use `Vec` (BT-974). #[derive(Debug, Clone, PartialEq)] pub struct ExpressionStatement { /// Comments attached to this statement. @@ -547,7 +548,7 @@ pub struct MethodDefinition { /// Method parameters with optional type annotations. pub parameters: Vec, /// The method body expressions. - pub body: Vec, + pub body: Vec, /// Optional return type annotation. pub return_type: Option, /// Whether this method is sealed (cannot be overridden). @@ -568,7 +569,7 @@ impl MethodDefinition { pub fn new( selector: MessageSelector, parameters: Vec, - body: Vec, + body: Vec, span: Span, ) -> Self { Self { @@ -589,7 +590,7 @@ impl MethodDefinition { pub fn with_return_type( selector: MessageSelector, parameters: Vec, - body: Vec, + body: Vec, return_type: TypeAnnotation, span: Span, ) -> Self { @@ -611,7 +612,7 @@ impl MethodDefinition { pub fn with_options( selector: MessageSelector, parameters: Vec, - body: Vec, + body: Vec, return_type: Option, is_sealed: bool, kind: MethodKind, @@ -1251,7 +1252,7 @@ pub struct Block { /// Block parameters. pub parameters: Vec, /// The expressions in the block body. - pub body: Vec, + pub body: Vec, /// Source location of the entire block (including brackets). pub span: Span, } @@ -1259,7 +1260,11 @@ pub struct Block { impl Block { /// Creates a new block. #[must_use] - pub fn new(parameters: Vec, body: Vec, span: Span) -> Self { + pub fn new( + parameters: Vec, + body: Vec, + span: Span, + ) -> Self { Self { parameters, body, @@ -1541,7 +1546,7 @@ mod tests { let module = Module::new(Vec::new(), span); assert!(module.expressions.is_empty()); assert_eq!(module.span, span); - assert!(module.leading_comments.is_empty()); + assert!(module.file_leading_comments.is_empty()); } #[test] @@ -1896,7 +1901,7 @@ mod tests { #[test] fn method_definition_unary() { let selector = MessageSelector::Unary("increment".into()); - let body = vec![Expression::Assignment { + let body = vec![ExpressionStatement::bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -1920,7 +1925,7 @@ mod tests { span: Span::new(14, 28), }), span: Span::new(0, 28), - }]; + })]; let method = MethodDefinition::new(selector, Vec::new(), body, Span::new(0, 28)); assert_eq!(method.selector.name(), "increment"); assert!(method.parameters.is_empty()); @@ -1935,9 +1940,8 @@ mod tests { "index", Span::new(4, 9), ))]; - let body = vec![Expression::Identifier(Identifier::new( - "result", - Span::new(13, 19), + let body = vec![ExpressionStatement::bare(Expression::Identifier( + Identifier::new("result", Span::new(13, 19)), ))]; let method = MethodDefinition::new(selector, params, body, Span::new(0, 19)); assert_eq!(method.selector.name(), "at:"); @@ -1948,7 +1952,7 @@ mod tests { #[test] fn method_definition_with_return_type() { let selector = MessageSelector::Unary("getValue".into()); - let body = vec![Expression::Return { + let body = vec![ExpressionStatement::bare(Expression::Return { value: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -1958,7 +1962,7 @@ mod tests { span: Span::new(0, 10), }), span: Span::new(0, 10), - }]; + })]; let return_type = TypeAnnotation::simple("Integer", Span::new(12, 19)); let method = MethodDefinition::with_return_type( selector, @@ -1984,7 +1988,7 @@ mod tests { let methods = vec![MethodDefinition::new( MessageSelector::Unary("increment".into()), Vec::new(), - vec![Expression::Assignment { + vec![ExpressionStatement::bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -2008,7 +2012,7 @@ mod tests { span: Span::new(64, 78), }), span: Span::new(50, 78), - }], + })], Span::new(45, 78), )]; diff --git a/crates/beamtalk-core/src/ast_walker.rs b/crates/beamtalk-core/src/ast_walker.rs index 0e6018a40..dfb9d13d7 100644 --- a/crates/beamtalk-core/src/ast_walker.rs +++ b/crates/beamtalk-core/src/ast_walker.rs @@ -29,7 +29,7 @@ //! awareness (e.g. `cascade_candidate`) keep their own recursive traversal. //! This module handles the common pre-order-visitor pattern. -use crate::ast::{Expression, Module, StringSegment}; +use crate::ast::{Expression, ExpressionStatement, Module, StringSegment}; // ── Module-level iterators ──────────────────────────────────────────────────── @@ -44,7 +44,7 @@ use crate::ast::{Expression, Module, StringSegment}; /// not top-level statement sequences. pub(crate) fn for_each_expr_seq(module: &Module, mut f: F) where - F: FnMut(&[Expression]), + F: FnMut(&[ExpressionStatement]), { f(&module.expressions); for class in &module.classes { @@ -81,8 +81,8 @@ where } } Expression::Block(block) => { - for e in &block.body { - walk_expression(e, f); + for stmt in &block.body { + walk_expression(&stmt.expression, f); } } Expression::Assignment { target, value, .. } => { @@ -165,8 +165,8 @@ where F: FnMut(&Expression), { for_each_expr_seq(module, |seq| { - for expr in seq { - walk_expression(expr, f); + for stmt in seq { + walk_expression(&stmt.expression, f); } }); } diff --git a/crates/beamtalk-core/src/codegen/core_erlang/actor_codegen.rs b/crates/beamtalk-core/src/codegen/core_erlang/actor_codegen.rs index 722cfa34d..5c355f03b 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/actor_codegen.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/actor_codegen.rs @@ -212,7 +212,7 @@ impl CoreErlangGenerator { c.methods.iter().any(|m| { m.body.len() == 1 && matches!( - &m.body[0], + &m.body[0].expression, Expression::Primitive { is_quoted: true, .. @@ -382,7 +382,7 @@ impl CoreErlangGenerator { let needs_nlr = method .body .iter() - .any(|expr| Self::expr_has_block_nlr(expr, false)); + .any(|stmt| Self::expr_has_block_nlr(&stmt.expression, false)); let nlr_token_var = if needs_nlr { let token_var = self.fresh_temp_var("NlrToken"); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/block_analysis.rs b/crates/beamtalk-core/src/codegen/core_erlang/block_analysis.rs index 810014e85..efe46e7fc 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/block_analysis.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/block_analysis.rs @@ -68,8 +68,8 @@ pub fn analyze_block(block: &Block) -> BlockMutationAnalysis { } // Analyze all expressions in the block body - for expr in &block.body { - analyze_expression(expr, &mut analysis, &mut ctx); + for stmt in &block.body { + analyze_expression(&stmt.expression, &mut analysis, &mut ctx); } analysis @@ -303,7 +303,7 @@ pub fn is_control_flow_construct( #[cfg(test)] mod tests { use super::*; - use crate::ast::{BlockParameter, Identifier}; + use crate::ast::{BlockParameter, ExpressionStatement, Identifier}; use crate::source_analysis::Span; fn make_id(name: &str) -> Identifier { @@ -314,6 +314,10 @@ mod tests { Expression::Identifier(make_id(name)) } + fn bare(expr: Expression) -> ExpressionStatement { + ExpressionStatement::bare(expr) + } + #[test] fn test_analyze_empty_block() { let block = Block::new(vec![], vec![], Span::new(0, 2)); @@ -328,7 +332,7 @@ mod tests { fn test_analyze_local_variable_read() { let block = Block::new( vec![BlockParameter::new("x", Span::new(0, 1))], - vec![make_expr_id("x")], + vec![bare(make_expr_id("x"))], Span::new(0, 5), ); let analysis = analyze_block(&block); @@ -340,14 +344,14 @@ mod tests { fn test_analyze_local_variable_write() { let block = Block::new( vec![], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(make_expr_id("count")), value: Box::new(Expression::Literal( crate::ast::Literal::Integer(0), Span::new(9, 10), )), span: Span::new(0, 10), - }], + })], Span::new(0, 12), ); let analysis = analyze_block(&block); @@ -360,7 +364,7 @@ mod tests { // Variable is a parameter, so it's in scope for both read and write let block = Block::new( vec![BlockParameter::new("count", Span::new(1, 6))], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(make_expr_id("count")), value: Box::new(Expression::MessageSend { receiver: Box::new(make_expr_id("count")), @@ -373,7 +377,7 @@ mod tests { span: Span::new(9, 17), }), span: Span::new(0, 17), - }], + })], Span::new(0, 19), ); let analysis = analyze_block(&block); @@ -388,11 +392,11 @@ mod tests { // [self.value] let block = Block::new( vec![], - vec![Expression::FieldAccess { + vec![bare(Expression::FieldAccess { receiver: Box::new(make_expr_id("self")), field: make_id("value"), span: Span::new(0, 10), - }], + })], Span::new(0, 12), ); let analysis = analyze_block(&block); @@ -405,7 +409,7 @@ mod tests { // [self.value := 0] let block = Block::new( vec![], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(make_expr_id("self")), field: make_id("value"), @@ -416,7 +420,7 @@ mod tests { Span::new(14, 15), )), span: Span::new(0, 15), - }], + })], Span::new(0, 17), ); let analysis = analyze_block(&block); @@ -430,7 +434,7 @@ mod tests { // Field writes in nested blocks must propagate to outer analysis let inner_block = Expression::Block(Block::new( vec![BlockParameter::new("j", Span::new(1, 2))], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(make_expr_id("self")), field: make_id("value"), @@ -451,13 +455,13 @@ mod tests { span: Span::new(0, 21), }), span: Span::new(0, 21), - }], + })], Span::new(0, 25), )); let outer_block = Block::new( vec![BlockParameter::new("i", Span::new(1, 2))], - vec![inner_block], + vec![bare(inner_block)], Span::new(0, 30), ); @@ -513,7 +517,7 @@ mod tests { // BT-665: [count := count + 1] — `count` is read before being locally defined let block = Block::new( vec![], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(make_expr_id("count")), value: Box::new(Expression::MessageSend { receiver: Box::new(make_expr_id("count")), @@ -526,7 +530,7 @@ mod tests { span: Span::new(9, 17), }), span: Span::new(0, 17), - }], + })], Span::new(0, 19), ); let analysis = analyze_block(&block); @@ -543,7 +547,7 @@ mod tests { let block = Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(make_expr_id("temp")), value: Box::new(Expression::MessageSend { receiver: Box::new(make_expr_id("x")), @@ -556,8 +560,8 @@ mod tests { span: Span::new(9, 17), }), span: Span::new(0, 17), - }, - Expression::MessageSend { + }), + bare(Expression::MessageSend { receiver: Box::new(make_expr_id("temp")), selector: MessageSelector::Binary("+".into()), arguments: vec![Expression::Literal( @@ -566,7 +570,7 @@ mod tests { )], is_cast: false, span: Span::new(19, 27), - }, + }), ], Span::new(0, 29), ); @@ -584,7 +588,7 @@ mod tests { // BT-665: [:x | x + 1] — `x` is a block param, not a captured read let block = Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(make_expr_id("x")), selector: MessageSelector::Binary("+".into()), arguments: vec![Expression::Literal( @@ -593,7 +597,7 @@ mod tests { )], is_cast: false, span: Span::new(3, 7), - }], + })], Span::new(0, 9), ); let analysis = analyze_block(&block); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/conditionals.rs b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/conditionals.rs index da311cda5..b8a064649 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/conditionals.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/conditionals.rs @@ -189,6 +189,7 @@ impl CoreErlangGenerator { /// /// Returns `(body_doc, final_state_version)`. The generated code ends with /// `{, }`. + #[allow(clippy::too_many_lines)] pub(in crate::codegen::core_erlang) fn generate_conditional_branch_inline( &mut self, block: &Block, @@ -199,6 +200,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = block .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/counted_loops.rs b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/counted_loops.rs index 6fb9fc0d7..a2faef74d 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/counted_loops.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/counted_loops.rs @@ -207,11 +207,15 @@ impl CoreErlangGenerator { // BT-478: Check if body has direct field assignments. If not, mutations // come from nested constructs and the last expression's result must be bound. - let has_direct_field_assignments = body.body.iter().any(Self::is_field_assignment); + let has_direct_field_assignments = body + .body + .iter() + .any(|s| Self::is_field_assignment(&s.expression)); let mut docs: Vec> = Vec::new(); - for (i, expr) in body.body.iter().enumerate() { + for (i, stmt) in body.body.iter().enumerate() { + let expr = &stmt.expression; if i > 0 { docs.push(Document::Str(" ")); } @@ -449,12 +453,16 @@ impl CoreErlangGenerator { // Direct field assignments update StateAcc via generate_field_assignment_open. // Nested mutations (e.g., inner to:do: with field writes) return the updated // state as the expression result. - let has_direct_field_assignments = body.body.iter().any(Self::is_field_assignment); + let has_direct_field_assignments = body + .body + .iter() + .any(|s| Self::is_field_assignment(&s.expression)); let mut docs: Vec> = Vec::new(); // Generate body expressions - for (i, expr) in body.body.iter().enumerate() { + for (i, stmt) in body.body.iter().enumerate() { + let expr = &stmt.expression; let is_last = i == body.body.len() - 1; if Self::is_field_assignment(expr) { diff --git a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/exception_handling.rs b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/exception_handling.rs index dd7164dee..f345aa1d2 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/exception_handling.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/exception_handling.rs @@ -502,12 +502,16 @@ impl CoreErlangGenerator { let previous_in_loop_body = self.in_loop_body; self.in_loop_body = true; - let has_direct_field_assignments = body.body.iter().any(Self::is_field_assignment); + let has_direct_field_assignments = body + .body + .iter() + .any(|s| Self::is_field_assignment(&s.expression)); let mut result_var = "'nil'".to_string(); let mut docs: Vec> = Vec::new(); - for (i, expr) in body.body.iter().enumerate() { + for (i, stmt) in body.body.iter().enumerate() { + let expr = &stmt.expression; if i > 0 { docs.push(Document::Str(" ")); } diff --git a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/list_ops.rs b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/list_ops.rs index 38201d7fd..5c9e7c0cf 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/list_ops.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/list_ops.rs @@ -203,6 +203,7 @@ impl CoreErlangGenerator { let filtered_body: Vec<&Expression> = body .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); for (i, expr) in filtered_body.iter().enumerate() { @@ -427,6 +428,7 @@ impl CoreErlangGenerator { let filtered_body: Vec<&Expression> = body .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); let mut has_mutations = false; @@ -720,6 +722,7 @@ impl CoreErlangGenerator { let filtered_body: Vec<&Expression> = body .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); let mut has_mutations = false; @@ -1120,6 +1123,7 @@ impl CoreErlangGenerator { let filtered_body: Vec<&Expression> = body .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); let mut has_mutations = false; diff --git a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/while_loops.rs b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/while_loops.rs index 24daa49d2..4f17f5074 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/control_flow/while_loops.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/control_flow/while_loops.rs @@ -203,11 +203,15 @@ impl CoreErlangGenerator { // BT-478: Check if body has direct field assignments. If not, mutations // come from nested constructs and the last expression's result must be bound. - let has_direct_field_assignments = body.body.iter().any(Self::is_field_assignment); + let has_direct_field_assignments = body + .body + .iter() + .any(|s| Self::is_field_assignment(&s.expression)); let mut docs: Vec> = Vec::new(); - for (i, expr) in body.body.iter().enumerate() { + for (i, stmt) in body.body.iter().enumerate() { + let expr = &stmt.expression; if i > 0 { docs.push(Document::Str(" ")); } diff --git a/crates/beamtalk-core/src/codegen/core_erlang/dispatch_codegen.rs b/crates/beamtalk-core/src/codegen/core_erlang/dispatch_codegen.rs index 9d3000278..3f45682f7 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/dispatch_codegen.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/dispatch_codegen.rs @@ -1521,8 +1521,8 @@ impl CoreErlangGenerator { self.tier2_method_info.clear(); for method in &class.methods { - for expr in &method.body { - self.scan_expr_for_tier2(expr, &analyze_block); + for stmt in &method.body { + self.scan_expr_for_tier2(&stmt.expression, &analyze_block); } } } @@ -1573,8 +1573,8 @@ impl CoreErlangGenerator { self.scan_expr_for_tier2(value, analyze); } Expression::Block(block) => { - for body_expr in &block.body { - self.scan_expr_for_tier2(body_expr, analyze); + for body_stmt in &block.body { + self.scan_expr_for_tier2(&body_stmt.expression, analyze); } } Expression::Return { value, .. } => { diff --git a/crates/beamtalk-core/src/codegen/core_erlang/expressions.rs b/crates/beamtalk-core/src/codegen/core_erlang/expressions.rs index 2345443e0..a12bdbd07 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/expressions.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/expressions.rs @@ -849,6 +849,7 @@ impl CoreErlangGenerator { let filtered_body: Vec<&Expression> = block .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); @@ -1204,6 +1205,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = block .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/dispatch.rs b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/dispatch.rs index 896bfce0f..09b225171 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/dispatch.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/dispatch.rs @@ -35,8 +35,8 @@ impl CoreErlangGenerator { let mut methods: Vec<(String, usize)> = module .expressions .iter() - .filter_map(|expr| { - if let Expression::Assignment { target, value, .. } = expr { + .filter_map(|stmt| { + if let Expression::Assignment { target, value, .. } = &stmt.expression { if let (Expression::Identifier(id), Expression::Block(block)) = (target.as_ref(), value.as_ref()) { @@ -106,8 +106,8 @@ impl CoreErlangGenerator { let mut methods: Vec = module .expressions .iter() - .filter_map(|expr| { - if let Expression::Assignment { target, value, .. } = expr { + .filter_map(|stmt| { + if let Expression::Assignment { target, value, .. } = &stmt.expression { if let (Expression::Identifier(id), Expression::Block(_)) = (target.as_ref(), value.as_ref()) { @@ -233,8 +233,8 @@ impl CoreErlangGenerator { let case_clause_indent: isize = 2; // Generate case clause for each method in the module (legacy expression-based) - for expr in &module.expressions { - if let Expression::Assignment { target, value, .. } = expr { + for stmt in &module.expressions { + if let Expression::Assignment { target, value, .. } = &stmt.expression { if let (Expression::Identifier(id), Expression::Block(block)) = (target.as_ref(), value.as_ref()) { @@ -256,7 +256,7 @@ impl CoreErlangGenerator { let needs_nlr = block .body .iter() - .any(|expr| Self::expr_has_block_nlr(expr, false)); + .any(|stmt| Self::expr_has_block_nlr(&stmt.expression, false)); let nlr_token_var = if needs_nlr { let token_var = self.fresh_temp_var("NlrToken"); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/methods.rs b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/methods.rs index fe184283a..fc9297c82 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/methods.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/methods.rs @@ -81,7 +81,7 @@ impl CoreErlangGenerator { let needs_nlr = method .body .iter() - .any(|expr| Self::expr_has_block_nlr(expr, false)); + .any(|stmt| Self::expr_has_block_nlr(&stmt.expression, false)); let nlr_token_var = if needs_nlr { let token_var = self.fresh_temp_var("NlrToken"); @@ -184,6 +184,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = method .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); for (i, expr) in body.iter().enumerate() { @@ -549,6 +550,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = block .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); for (i, expr) in body.iter().enumerate() { @@ -954,12 +956,12 @@ impl CoreErlangGenerator { } /// Check if a method body is a single `self error: ` expression. - fn is_self_error_body(body: &[Expression]) -> bool { + fn is_self_error_body(body: &[crate::ast::ExpressionStatement]) -> bool { if body.len() != 1 { return false; } matches!( - &body[0], + &body[0].expression, Expression::MessageSend { receiver, selector: MessageSelector::Keyword(parts), @@ -1516,6 +1518,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = method .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); for (i, expr) in body.iter().enumerate() { diff --git a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/state.rs b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/state.rs index dc062495b..f39f036ae 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/gen_server/state.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/gen_server/state.rs @@ -71,8 +71,8 @@ impl CoreErlangGenerator { // Initialize fields from module expressions (assignments at top level) // Only include literal values - blocks are methods handled by dispatch/3 - for expr in &module.expressions { - if let Expression::Assignment { target, value, .. } = expr { + for stmt in &module.expressions { + if let Expression::Assignment { target, value, .. } = &stmt.expression { if let Expression::Identifier(id) = target.as_ref() { if matches!(value.as_ref(), Expression::Literal(..)) { let value_code = self.expression_doc(value)?; diff --git a/crates/beamtalk-core/src/codegen/core_erlang/intrinsics.rs b/crates/beamtalk-core/src/codegen/core_erlang/intrinsics.rs index 188787caf..27163c46e 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/intrinsics.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/intrinsics.rs @@ -1256,14 +1256,17 @@ impl CoreErlangGenerator { #[cfg(test)] mod tests { use super::*; - use crate::ast::{Block, BlockParameter, Literal}; + use crate::ast::{Block, BlockParameter, ExpressionStatement, Literal}; use crate::source_analysis::Span; #[test] fn test_validate_if_not_nil_block_zero_args() { let block = Expression::Block(Block { parameters: vec![], - body: vec![Expression::Literal(Literal::Integer(1), Span::new(1, 2))], + body: vec![ExpressionStatement::bare(Expression::Literal( + Literal::Integer(1), + Span::new(1, 2), + ))], span: Span::new(0, 3), }); assert!(!validate_if_not_nil_block(&block, "ifNotNil:").unwrap()); @@ -1273,7 +1276,10 @@ mod tests { fn test_validate_if_not_nil_block_one_arg() { let block = Expression::Block(Block { parameters: vec![BlockParameter::new("v", Span::new(1, 2))], - body: vec![Expression::Literal(Literal::Integer(1), Span::new(5, 6))], + body: vec![ExpressionStatement::bare(Expression::Literal( + Literal::Integer(1), + Span::new(5, 6), + ))], span: Span::new(0, 7), }); assert!(validate_if_not_nil_block(&block, "ifNotNil:").unwrap()); @@ -1286,7 +1292,10 @@ mod tests { BlockParameter::new("a", Span::new(1, 2)), BlockParameter::new("b", Span::new(3, 4)), ], - body: vec![Expression::Literal(Literal::Integer(1), Span::new(7, 8))], + body: vec![ExpressionStatement::bare(Expression::Literal( + Literal::Integer(1), + Span::new(7, 8), + ))], span: Span::new(0, 9), }); let result = validate_if_not_nil_block(&block, "ifNotNil:"); @@ -1319,7 +1328,10 @@ mod tests { .collect(); Expression::Block(Block { parameters: params, - body: vec![Expression::Literal(Literal::Integer(1), Span::new(1, 2))], + body: vec![ExpressionStatement::bare(Expression::Literal( + Literal::Integer(1), + Span::new(1, 2), + ))], span: Span::new(0, 10), }) } diff --git a/crates/beamtalk-core/src/codegen/core_erlang/primitive_bindings.rs b/crates/beamtalk-core/src/codegen/core_erlang/primitive_bindings.rs index 634419559..67b3e6286 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/primitive_bindings.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/primitive_bindings.rs @@ -86,7 +86,7 @@ impl PrimitiveBindingTable { if method.body.len() == 1 { if let Expression::Primitive { name, is_quoted, .. - } = &method.body[0] + } = &method.body[0].expression { let selector = method.selector.to_erlang_atom(); let binding = if *is_quoted { @@ -233,8 +233,8 @@ pub fn load_from_directory(lib_dir: &std::path::Path) -> PrimitiveBindingTable { mod tests { use super::*; use crate::ast::{ - ClassDefinition, Expression, Identifier, KeywordPart, MessageSelector, MethodDefinition, - Module, ParameterDefinition, + ClassDefinition, Expression, ExpressionStatement, Identifier, KeywordPart, MessageSelector, + MethodDefinition, Module, ParameterDefinition, }; use crate::source_analysis::Span; @@ -251,11 +251,11 @@ mod tests { MethodDefinition::new( selector, params, - vec![Expression::Primitive { + vec![ExpressionStatement::bare(Expression::Primitive { name: prim_name.into(), is_quoted, span: span(), - }], + })], span(), ) } @@ -264,10 +264,10 @@ mod tests { MethodDefinition::new( selector, vec![], - vec![Expression::Literal( + vec![ExpressionStatement::bare(Expression::Literal( crate::ast::Literal::Integer(42), span(), - )], + ))], span(), ) } diff --git a/crates/beamtalk-core/src/codegen/core_erlang/tests.rs b/crates/beamtalk-core/src/codegen/core_erlang/tests.rs index c67df9716..9342f74e2 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/tests.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/tests.rs @@ -7,6 +7,10 @@ use super::*; use crate::ast::*; use crate::source_analysis::Span; +fn bare(expr: Expression) -> ExpressionStatement { + ExpressionStatement::bare(expr) +} + #[test] fn test_generate_empty_module() { let module = Module::new(Vec::new(), Span::new(0, 0)); @@ -536,7 +540,7 @@ fn test_generate_spawn_function() { span: Span::new(0, 10), }; - let module = Module::new(vec![value_assignment], Span::new(0, 10)); + let module = Module::new(vec![bare(value_assignment)], Span::new(0, 10)); let code = generate_module(&module, CodegenOptions::new("counter")).expect("codegen should succeed"); @@ -612,7 +616,7 @@ fn test_bt897_subdirectory_module_name_consistency() { expressions: vec![], method_definitions: vec![], span: Span::new(0, 50), - leading_comments: vec![], + file_leading_comments: vec![], }; // Use a subdirectory-qualified module name (package mode with subdirectories) @@ -753,7 +757,7 @@ fn test_generate_repl_module_block_value_call() { // Expression: [:x | x + 1] value: 5 let block = Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(5, 6), @@ -762,7 +766,7 @@ fn test_generate_repl_module_block_value_call() { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(9, 10))], is_cast: false, span: Span::new(5, 10), - }], + })], Span::new(0, 12), ); @@ -828,7 +832,7 @@ fn test_generate_repl_module_with_times_repeat_mutation() { }; let body = Expression::Block(Block { parameters: vec![], - body: vec![assignment], + body: vec![bare(assignment)], span: Span::new(0, 25), }); @@ -902,7 +906,7 @@ fn test_generate_repl_module_with_to_do_mutation() { name: "n".into(), span: Span::new(0, 1), }], - body: vec![assignment], + body: vec![bare(assignment)], span: Span::new(0, 25), }); @@ -965,7 +969,7 @@ fn test_generate_repl_module_with_while_true_mutation() { }; let condition = Expression::Block(Block { parameters: vec![], - body: vec![compare], + body: vec![bare(compare)], span: Span::new(0, 12), }); @@ -985,7 +989,7 @@ fn test_generate_repl_module_with_while_true_mutation() { }; let body = Expression::Block(Block { parameters: vec![], - body: vec![assignment], + body: vec![bare(assignment)], span: Span::new(0, 17), }); @@ -1032,8 +1036,15 @@ fn test_repl_multi_stmt_times_repeat_intermediate() { let src = "x := 1. 5 timesRepeat: [x := x + 1]. x"; let tokens = crate::source_analysis::lex_with_eof(src); let (module, _diags) = crate::source_analysis::parse(tokens); - let code = generate_repl_expressions(&module.expressions, "repl_multi_times_test") - .expect("codegen should work"); + let code = generate_repl_expressions( + &module + .expressions + .iter() + .map(|s| s.expression.clone()) + .collect::>(), + "repl_multi_times_test", + ) + .expect("codegen should work"); eprintln!("Generated code for `x := 1. 5 timesRepeat: [x := x + 1]. x`:"); eprintln!("{code}"); @@ -1071,8 +1082,15 @@ fn test_repl_multi_stmt_while_true_intermediate() { let src = "x := 0. [x < 3] whileTrue: [x := x + 1]. x"; let tokens = crate::source_analysis::lex_with_eof(src); let (module, _diags) = crate::source_analysis::parse(tokens); - let code = generate_repl_expressions(&module.expressions, "repl_multi_while_test") - .expect("codegen should work"); + let code = generate_repl_expressions( + &module + .expressions + .iter() + .map(|s| s.expression.clone()) + .collect::>(), + "repl_multi_while_test", + ) + .expect("codegen should work"); eprintln!("Generated code for `x := 0. [x < 3] whileTrue: [x := x + 1]. x`:"); eprintln!("{code}"); @@ -1104,8 +1122,15 @@ fn test_repl_multi_stmt_assignment_then_loop_then_plain() { let src = "count := 0. 3 timesRepeat: [count := count + 1]. count"; let tokens = crate::source_analysis::lex_with_eof(src); let (module, _diags) = crate::source_analysis::parse(tokens); - let code = generate_repl_expressions(&module.expressions, "repl_multi_chain_test") - .expect("codegen should work"); + let code = generate_repl_expressions( + &module + .expressions + .iter() + .map(|s| s.expression.clone()) + .collect::>(), + "repl_multi_chain_test", + ) + .expect("codegen should work"); eprintln!("Generated code for `count := 0. 3 timesRepeat: [count := count + 1]. count`:"); eprintln!("{code}"); @@ -1207,7 +1232,7 @@ fn test_generate_repl_multi_stmt_times_repeat_then_read() { }; let loop_body = Expression::Block(Block { parameters: vec![], - body: vec![loop_assign], + body: vec![bare(loop_assign)], span, }); let five = Expression::Literal(Literal::Integer(5), span); @@ -1284,7 +1309,7 @@ fn test_generate_repl_multi_stmt_while_true_then_read() { }; let condition = Expression::Block(Block { parameters: vec![], - body: vec![cmp], + body: vec![bare(cmp)], span, }); let x_body = Expression::Identifier(Identifier::new("x", span)); @@ -1303,7 +1328,7 @@ fn test_generate_repl_multi_stmt_while_true_then_read() { }; let loop_body = Expression::Block(Block { parameters: vec![], - body: vec![loop_assign], + body: vec![bare(loop_assign)], span, }); let while_true = Expression::MessageSend { @@ -1380,7 +1405,7 @@ fn test_generate_repl_multi_stmt_loop_does_not_corrupt_final_expr() { }; let loop_body = Expression::Block(Block { parameters: vec![], - body: vec![loop_assign], + body: vec![bare(loop_assign)], span, }); let five = Expression::Literal(Literal::Integer(5), span); @@ -1452,7 +1477,7 @@ fn test_repl_loop_mutations_accumulate_plain_key() { }; let body = Expression::Block(Block { parameters: vec![], - body: vec![assignment], + body: vec![bare(assignment)], span, }); let five = Expression::Literal(Literal::Integer(5), span); @@ -1534,7 +1559,7 @@ fn test_repl_multi_stmt_loop_accumulates_from_zero() { }; let loop_body = Expression::Block(Block { parameters: vec![], - body: vec![loop_assign], + body: vec![bare(loop_assign)], span, }); let five = Expression::Literal(Literal::Integer(5), span); @@ -1595,7 +1620,10 @@ fn test_block_value_message_no_args() { let block = Block::new( vec![], - vec![Expression::Literal(Literal::Integer(42), Span::new(1, 3))], + vec![bare(Expression::Literal( + Literal::Integer(42), + Span::new(1, 3), + ))], Span::new(0, 4), ); let receiver = Expression::Block(block); @@ -1623,7 +1651,7 @@ fn test_block_value_message_one_arg() { let block = Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(5, 6), @@ -1632,7 +1660,7 @@ fn test_block_value_message_one_arg() { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(9, 10))], is_cast: false, span: Span::new(5, 10), - }], + })], Span::new(0, 12), ); let receiver = Expression::Block(block); @@ -1672,7 +1700,10 @@ fn test_block_value_message_two_args() { BlockParameter::new("x", Span::new(1, 2)), BlockParameter::new("y", Span::new(4, 5)), ], - vec![Expression::Literal(Literal::Integer(0), Span::new(8, 9))], // placeholder body + vec![bare(Expression::Literal( + Literal::Integer(0), + Span::new(8, 9), + ))], // placeholder body Span::new(0, 11), ); let receiver = Expression::Block(block); @@ -1707,7 +1738,7 @@ fn test_block_while_true_loop() { // Condition block: [counter < 5] let condition_block = Block::new( vec![], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "counter", Span::new(1, 8), @@ -1716,14 +1747,17 @@ fn test_block_while_true_loop() { arguments: vec![Expression::Literal(Literal::Integer(5), Span::new(11, 12))], is_cast: false, span: Span::new(1, 12), - }], + })], Span::new(0, 13), ); // Body block: [counter := counter + 1] let body_block = Block::new( vec![], - vec![Expression::Literal(Literal::Integer(0), Span::new(0, 1))], // simplified body + vec![bare(Expression::Literal( + Literal::Integer(0), + Span::new(0, 1), + ))], // simplified body Span::new(15, 38), ); @@ -1766,10 +1800,10 @@ fn test_block_while_false_loop() { let condition_block = Block::new( vec![], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "done", Span::new(1, 5), - ))], + )))], Span::new(0, 6), ); let body_block = Block::new(vec![], vec![], Span::new(8, 10)); @@ -1804,7 +1838,10 @@ fn test_block_repeat_infinite_loop() { let body_block = Block::new( vec![], - vec![Expression::Literal(Literal::Integer(1), Span::new(1, 2))], + vec![bare(Expression::Literal( + Literal::Integer(1), + Span::new(1, 2), + ))], Span::new(0, 3), ); @@ -1871,15 +1908,18 @@ fn test_while_true_compiles_through_erlc() { // This creates a loop that runs once (returns nil after first iteration) let condition_block = Block::new( vec![], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "false", Span::new(1, 6), - ))], + )))], Span::new(0, 7), ); let body_block = Block::new( vec![], - vec![Expression::Literal(Literal::Integer(42), Span::new(9, 11))], + vec![bare(Expression::Literal( + Literal::Integer(42), + Span::new(9, 11), + ))], Span::new(8, 12), ); @@ -1941,10 +1981,10 @@ fn test_temp_vars_dont_shadow_user_identifiers() { // First, generate a whileTrue: which creates internal _Loop, _Cond, _Body temps let condition_block = Block::new( vec![], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "false", Span::new(1, 6), - ))], + )))], Span::new(0, 7), ); let body_block = Block::new(vec![], vec![], Span::new(8, 10)); @@ -2551,7 +2591,7 @@ fn test_validate_stored_closure_with_captured_mutation() { // `count` is read (captured from outer scope) and written → should error let block = Block { parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(1, 6), @@ -2567,7 +2607,7 @@ fn test_validate_stored_closure_with_captured_mutation() { span: Span::new(10, 19), }), span: Span::new(1, 19), - }], + })], span: Span::new(0, 20), }; @@ -2590,14 +2630,14 @@ fn test_validate_stored_closure_with_new_local_definition() { // `temp` is never read from outer scope → should be allowed let block = Block { parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "temp", Span::new(1, 5), ))), value: Box::new(Expression::Literal(Literal::Integer(1), Span::new(9, 10))), span: Span::new(1, 10), - }], + })], span: Span::new(0, 11), }; @@ -2615,7 +2655,7 @@ fn test_validate_stored_closure_with_new_local_used_later() { let block = Block { parameters: vec![BlockParameter::new("x", Span::new(1, 2))], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "temp", Span::new(5, 9), @@ -2631,8 +2671,8 @@ fn test_validate_stored_closure_with_new_local_used_later() { span: Span::new(13, 18), }), span: Span::new(5, 18), - }, - Expression::MessageSend { + }), + bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "temp", Span::new(20, 24), @@ -2641,7 +2681,7 @@ fn test_validate_stored_closure_with_new_local_used_later() { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(27, 28))], is_cast: false, span: Span::new(20, 28), - }, + }), ], span: Span::new(0, 29), }; @@ -2658,7 +2698,7 @@ fn test_validate_stored_closure_with_field_assignment() { // Block with field assignment: [self.value := 1] let block = Block { parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -2669,7 +2709,7 @@ fn test_validate_stored_closure_with_field_assignment() { }), value: Box::new(Expression::Literal(Literal::Integer(1), Span::new(15, 16))), span: Span::new(1, 16), - }], + })], span: Span::new(0, 17), }; @@ -2696,15 +2736,15 @@ fn test_validate_stored_closure_field_takes_precedence() { let block = Block { parameters: vec![], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(1, 6), ))), value: Box::new(Expression::Literal(Literal::Integer(0), Span::new(10, 11))), span: Span::new(1, 11), - }, - Expression::Assignment { + }), + bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -2715,7 +2755,7 @@ fn test_validate_stored_closure_field_takes_precedence() { }), value: Box::new(Expression::Literal(Literal::Integer(1), Span::new(27, 28))), span: Span::new(13, 28), - }, + }), ], span: Span::new(0, 29), }; @@ -2740,7 +2780,7 @@ fn test_codegen_rejects_stored_closure_with_field_assignment() { let module = Module { classes: vec![], method_definitions: Vec::new(), - expressions: vec![Expression::Assignment { + expressions: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "test", Span::new(0, 4), @@ -2749,14 +2789,14 @@ fn test_codegen_rejects_stored_closure_with_field_assignment() { parameters: vec![], body: vec![ // myBlock := [self.value := self.value + 1] - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "myBlock", Span::new(10, 17), ))), value: Box::new(Expression::Block(Block { parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", @@ -2770,19 +2810,22 @@ fn test_codegen_rejects_stored_closure_with_field_assignment() { Span::new(36, 37), )), span: Span::new(22, 37), - }], + })], span: Span::new(21, 38), })), span: Span::new(10, 38), - }, - Expression::Identifier(Identifier::new("myBlock", Span::new(40, 47))), + }), + bare(Expression::Identifier(Identifier::new( + "myBlock", + Span::new(40, 47), + ))), ], span: Span::new(8, 49), })), span: Span::new(0, 49), - }], + })], span: Span::new(0, 50), - leading_comments: vec![], + file_leading_comments: vec![], }; // BT-852: Stored closures with field assignments are now allowed via Tier 2 protocol. @@ -2800,7 +2843,7 @@ fn test_codegen_rejects_stored_closure_with_local_mutation() { let module = Module { classes: vec![], method_definitions: Vec::new(), - expressions: vec![Expression::Assignment { + expressions: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "test", Span::new(0, 4), @@ -2809,7 +2852,7 @@ fn test_codegen_rejects_stored_closure_with_local_mutation() { parameters: vec![], body: vec![ // count := 0 - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(10, 15), @@ -2819,16 +2862,16 @@ fn test_codegen_rejects_stored_closure_with_local_mutation() { Span::new(19, 20), )), span: Span::new(10, 20), - }, + }), // myBlock := [count := count + 1] - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "myBlock", Span::new(22, 29), ))), value: Box::new(Expression::Block(Block { parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(34, 39), @@ -2847,19 +2890,22 @@ fn test_codegen_rejects_stored_closure_with_local_mutation() { span: Span::new(43, 52), }), span: Span::new(34, 52), - }], + })], span: Span::new(33, 53), })), span: Span::new(22, 53), - }, - Expression::Identifier(Identifier::new("myBlock", Span::new(55, 62))), + }), + bare(Expression::Identifier(Identifier::new( + "myBlock", + Span::new(55, 62), + ))), ], span: Span::new(8, 64), })), span: Span::new(0, 64), - }], + })], span: Span::new(0, 65), - leading_comments: vec![], + file_leading_comments: vec![], }; // BT-852: Stored closures with local mutations are now allowed via Tier 2 protocol. @@ -2900,7 +2946,10 @@ fn test_class_registration_generation() { MethodDefinition { selector: MessageSelector::Unary("increment".into()), parameters: vec![], - body: vec![Expression::Literal(Literal::Integer(42), Span::new(0, 2))], + body: vec![bare(Expression::Literal( + Literal::Integer(42), + Span::new(0, 2), + ))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2911,7 +2960,10 @@ fn test_class_registration_generation() { MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Literal(Literal::Integer(42), Span::new(0, 2))], + body: vec![bare(Expression::Literal( + Literal::Integer(42), + Span::new(0, 2), + ))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2932,7 +2984,7 @@ fn test_class_registration_generation() { classes: vec![class], method_definitions: Vec::new(), span: Span::new(0, 50), - leading_comments: vec![], + file_leading_comments: vec![], }; let code = @@ -3098,7 +3150,7 @@ fn test_multiple_classes_registration() { ], method_definitions: Vec::new(), span: Span::new(0, 50), - leading_comments: vec![], + file_leading_comments: vec![], }; let code = generate_module(&module, CodegenOptions::new("multi_actors")) @@ -3222,7 +3274,7 @@ fn test_multi_class_early_error_short_circuits() { classes: vec![make_class("ShadowA", 7, 20), make_class("ValidB", 6, 30)], method_definitions: Vec::new(), span: Span::new(0, 50), - leading_comments: vec![], + file_leading_comments: vec![], }; let code = generate_module(&module, CodegenOptions::new("multi_shadow")) @@ -3290,7 +3342,7 @@ fn test_three_class_short_circuit_nesting() { classes: vec![make_class("A", 1), make_class("B", 1), make_class("C", 1)], method_definitions: Vec::new(), span: Span::new(0, 60), - leading_comments: vec![], + file_leading_comments: vec![], }; let code = generate_module(&module, CodegenOptions::new("three_classes")) @@ -3466,14 +3518,14 @@ fn test_standalone_class_reference_uses_dynamic_module_name() { }; let module = Module { - expressions: vec![expr], + expressions: vec![bare(expr)], classes: vec![], method_definitions: Vec::new(), span: Span::new(0, 5), - leading_comments: vec![], + file_leading_comments: vec![], }; - let code = generate_repl_expression(&module.expressions[0], "repl_eval") + let code = generate_repl_expression(&module.expressions[0].expression, "repl_eval") .expect("codegen should succeed"); // Should call whereis_class to get the class PID @@ -3514,14 +3566,14 @@ fn test_standalone_class_reference_validates_undefined_classes() { }; let module = Module { - expressions: vec![expr], + expressions: vec![bare(expr)], classes: vec![], method_definitions: Vec::new(), span: Span::new(0, 16), - leading_comments: vec![], + file_leading_comments: vec![], }; - let code = generate_repl_expression(&module.expressions[0], "repl_eval") + let code = generate_repl_expression(&module.expressions[0].expression, "repl_eval") .expect("codegen should succeed"); // Should use a case expression to check for undefined @@ -3575,7 +3627,7 @@ fn test_is_actor_class_direct_actor_subclass() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3605,7 +3657,7 @@ fn test_is_actor_class_object_subclass_is_value_type() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3653,7 +3705,7 @@ fn test_is_actor_class_multi_level_inheritance() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3665,7 +3717,7 @@ fn test_is_actor_class_multi_level_inheritance() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; // Build hierarchy from full module so Counter is known assert!(CoreErlangGenerator::is_actor_class(&module_lc, &hierarchy)); @@ -3704,7 +3756,7 @@ fn test_is_actor_class_unknown_superclass_defaults_to_actor() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3735,7 +3787,7 @@ fn test_is_actor_class_collection_subclass_is_value_type() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3770,7 +3822,7 @@ fn test_is_actor_class_integer_subclass_is_value_type() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3804,7 +3856,7 @@ fn test_is_actor_class_root_class_is_value_type() { method_definitions: Vec::new(), expressions: vec![], span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = crate::semantic_analysis::class_hierarchy::ClassHierarchy::build(&module) .0 @@ -3880,7 +3932,7 @@ fn test_generate_with_bindings_compiles_value_type() { method_definitions: Vec::new(), expressions: Vec::new(), span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let bindings = primitive_bindings::PrimitiveBindingTable::new(); @@ -3901,7 +3953,7 @@ fn test_generate_repl_list_reject() { let src = "#(1, 2, 3, 4, 5) reject: [:x | x > 2]"; let tokens = crate::source_analysis::lex_with_eof(src); let (module, _diags) = crate::source_analysis::parse(tokens); - let expr = &module.expressions[0]; + let expr = &module.expressions[0].expression; let code = generate_repl_expression(expr, "test_reject_repl").expect("codegen should work"); // Wrapper fun must be bound to a variable, not inlined in filter call @@ -4410,7 +4462,7 @@ fn test_bt855_erlang_interop_wrapper_pure_block_no_warning() { // Pure block: [:x | x + 1] let pure_block = Expression::Block(Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(5, 6), @@ -4419,7 +4471,7 @@ fn test_bt855_erlang_interop_wrapper_pure_block_no_warning() { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(9, 10))], is_cast: false, span: Span::new(5, 10), - }], + })], Span::new(0, 11), )); @@ -4482,7 +4534,7 @@ fn test_bt855_erlang_interop_wrapper_stateful_block_emits_warning() { // 'count' is read (captured from outer scope) and written (local_writes) → Tier 2 let stateful_block = Expression::Block(Block::new( vec![BlockParameter::new("x", Span::new(1, 2))], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(5, 10), @@ -4501,7 +4553,7 @@ fn test_bt855_erlang_interop_wrapper_stateful_block_emits_warning() { span: Span::new(14, 23), }), span: Span::new(5, 23), - }], + })], Span::new(0, 24), )); @@ -4595,7 +4647,7 @@ fn test_bt855_generate_erlang_interop_wrapper_pure_returns_tier1() { let pure_block = Block::new( vec![BlockParameter::new("x", Span::new(0, 1))], - vec![Expression::MessageSend { + vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(3, 4), @@ -4604,7 +4656,7 @@ fn test_bt855_generate_erlang_interop_wrapper_pure_returns_tier1() { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(7, 8))], is_cast: false, span: Span::new(3, 8), - }], + })], Span::new(0, 9), ); @@ -4641,7 +4693,7 @@ fn test_bt855_generate_erlang_interop_wrapper_stateful_returns_wrapper() { // Stateful block: [:x | count := count + x] let stateful_block = Block::new( vec![BlockParameter::new("x", Span::new(0, 1))], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", Span::new(3, 8), @@ -4660,7 +4712,7 @@ fn test_bt855_generate_erlang_interop_wrapper_stateful_returns_wrapper() { span: Span::new(12, 21), }), span: Span::new(3, 21), - }], + })], Span::new(0, 22), ); @@ -5149,7 +5201,7 @@ sealed Object subclass: Bar "Warning should explain the issue. Got: {msg}" ); // Verify the span points at the @primitive expression, not a dummy zero span. - let primitive_span = match &module.classes[0].methods[0].body[0] { + let primitive_span = match &module.classes[0].methods[0].body[0].expression { Expression::Primitive { span, .. } => *span, other => panic!("Expected Primitive expression, got: {other:?}"), }; @@ -5238,7 +5290,7 @@ fn make_value_subclass_point() -> Module { method_definitions: Vec::new(), expressions: Vec::new(), span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], } } @@ -5419,7 +5471,7 @@ fn test_object_subclass_no_auto_getters() { method_definitions: Vec::new(), expressions: Vec::new(), span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = generate_module(&module, CodegenOptions::new("bt@point")); let code = result.unwrap(); @@ -5442,7 +5494,10 @@ fn test_value_subclass_user_defined_overrides_auto() { selector: MessageSelector::Unary("x".into()), parameters: vec![], return_type: None, - body: vec![Expression::Literal(Literal::Integer(99), Span::new(0, 0))], + body: vec![bare(Expression::Literal( + Literal::Integer(99), + Span::new(0, 0), + ))], kind: MethodKind::Primary, is_sealed: false, comments: CommentAttachment::default(), @@ -5476,7 +5531,7 @@ fn test_value_subclass_user_defined_overrides_auto() { method_definitions: Vec::new(), expressions: Vec::new(), span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = generate_module(&module, CodegenOptions::new("bt@my_val")); let code = result.unwrap(); @@ -5511,7 +5566,7 @@ fn test_value_subclass_no_slots_no_keyword_constructor() { method_definitions: Vec::new(), expressions: Vec::new(), span: Span::new(0, 0), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = generate_module(&module, CodegenOptions::new("bt@empty")); let code = result.unwrap(); diff --git a/crates/beamtalk-core/src/codegen/core_erlang/value_type_codegen.rs b/crates/beamtalk-core/src/codegen/core_erlang/value_type_codegen.rs index 164aab3ef..988a3c3de 100644 --- a/crates/beamtalk-core/src/codegen/core_erlang/value_type_codegen.rs +++ b/crates/beamtalk-core/src/codegen/core_erlang/value_type_codegen.rs @@ -454,8 +454,8 @@ impl CoreErlangGenerator { let prim_name = new_method .body .iter() - .find_map(|expr| { - if let crate::ast::Expression::Primitive { name, .. } = expr { + .find_map(|stmt| { + if let crate::ast::Expression::Primitive { name, .. } = &stmt.expression { Some(name.clone()) } else { None @@ -737,7 +737,7 @@ impl CoreErlangGenerator { let needs_nlr = method .body .iter() - .any(|expr| Self::expr_has_block_nlr(expr, false)); + .any(|stmt| Self::expr_has_block_nlr(&stmt.expression, false)); let nlr_token_var = if needs_nlr { let token_var = self.fresh_temp_var("NlrToken"); @@ -758,6 +758,7 @@ impl CoreErlangGenerator { let body: Vec<&Expression> = method .body .iter() + .map(|s| &s.expression) .filter(|e| !matches!(e, Expression::ExpectDirective { .. })) .collect(); @@ -1082,7 +1083,10 @@ impl CoreErlangGenerator { /// Returns `true` if the block (or any expression inside it, recursively) /// contains a `^` (Return) expression. fn block_has_nlr(block: &Block) -> bool { - block.body.iter().any(|e| Self::expr_has_block_nlr(e, true)) + block + .body + .iter() + .any(|s| Self::expr_has_block_nlr(&s.expression, true)) } /// Returns true if the class is a non-instantiable primitive type. @@ -1294,7 +1298,7 @@ impl CoreErlangGenerator { let has_nlr = method .body .iter() - .any(|expr| Self::expr_has_block_nlr(expr, false)); + .any(|stmt| Self::expr_has_block_nlr(&stmt.expression, false)); // Build the method call arguments: (Self) or (Self, DispArg0, DispArg1, ...) if !method.parameters.is_empty() { diff --git a/crates/beamtalk-core/src/codegen/property_tests.rs b/crates/beamtalk-core/src/codegen/property_tests.rs index f0f69397e..3ef8d8f13 100644 --- a/crates/beamtalk-core/src/codegen/property_tests.rs +++ b/crates/beamtalk-core/src/codegen/property_tests.rs @@ -122,7 +122,7 @@ proptest! { fn generate_repl_expression_never_panics(input in "\\PC{0,300}") { let module = parse_source(&input); for expr in &module.expressions { - let _result = generate_repl_expression(expr, "prop_test_repl"); + let _result = generate_repl_expression(&expr.expression, "prop_test_repl"); } } @@ -131,7 +131,7 @@ proptest! { fn generate_repl_expression_never_panics_near_valid(input in near_valid_beamtalk()) { let module = parse_source(&input); for expr in &module.expressions { - let _result = generate_repl_expression(expr, "prop_test_repl"); + let _result = generate_repl_expression(&expr.expression, "prop_test_repl"); } } @@ -163,7 +163,7 @@ proptest! { fn repl_codegen_output_structure(input in near_valid_beamtalk()) { let module = parse_source(&input); for expr in &module.expressions { - if let Ok(output) = generate_repl_expression(expr, "prop_test_repl") { + if let Ok(output) = generate_repl_expression(&expr.expression, "prop_test_repl") { prop_assert!( !output.is_empty(), "generate_repl_expression returned Ok with empty output for input {:?}", diff --git a/crates/beamtalk-core/src/language_service/mod.rs b/crates/beamtalk-core/src/language_service/mod.rs index a63228006..c7cca89b4 100644 --- a/crates/beamtalk-core/src/language_service/mod.rs +++ b/crates/beamtalk-core/src/language_service/mod.rs @@ -188,20 +188,22 @@ impl SimpleLanguageService { offset: u32, ) -> Option { // Check top-level expressions - for expr in &module.expressions { - if let Some(result) = - crate::queries::definition_provider::find_selector_lookup_in_expr(expr, offset) - { + for stmt in &module.expressions { + if let Some(result) = crate::queries::definition_provider::find_selector_lookup_in_expr( + &stmt.expression, + offset, + ) { return Some(result); } } // Check class method bodies for class in &module.classes { for method in class.methods.iter().chain(class.class_methods.iter()) { - for expr in &method.body { + for stmt in &method.body { if let Some(result) = crate::queries::definition_provider::find_selector_lookup_in_expr( - expr, offset, + &stmt.expression, + offset, ) { return Some(result); @@ -211,9 +213,12 @@ impl SimpleLanguageService { } // Check standalone method bodies for smd in &module.method_definitions { - for expr in &smd.method.body { + for stmt in &smd.method.body { if let Some(result) = - crate::queries::definition_provider::find_selector_lookup_in_expr(expr, offset) + crate::queries::definition_provider::find_selector_lookup_in_expr( + &stmt.expression, + offset, + ) { return Some(result); } @@ -271,8 +276,8 @@ impl SimpleLanguageService { return Some(ident); } } - for expr in &method.body { - if let Some(ident) = Self::find_identifier_in_expr(expr, offset) { + for stmt in &method.body { + if let Some(ident) = Self::find_identifier_in_expr(&stmt.expression, offset) { return Some(ident); } } @@ -302,16 +307,16 @@ impl SimpleLanguageService { } } - for expr in &smd.method.body { - if let Some(ident) = Self::find_identifier_in_expr(expr, offset) { + for stmt in &smd.method.body { + if let Some(ident) = Self::find_identifier_in_expr(&stmt.expression, offset) { return Some(ident); } } } // Walk the top-level expressions - for expr in &file_data.module.expressions { - if let Some(ident) = Self::find_identifier_in_expr(expr, offset) { + for stmt in &file_data.module.expressions { + if let Some(ident) = Self::find_identifier_in_expr(&stmt.expression, offset) { return Some(ident); } } @@ -393,7 +398,7 @@ impl SimpleLanguageService { Expression::Block(block) => block .body .iter() - .find_map(|expr| Self::find_identifier_in_expr(expr, offset)), + .find_map(|stmt| Self::find_identifier_in_expr(&stmt.expression, offset)), Expression::Return { value, .. } => Self::find_identifier_in_expr(value, offset), Expression::Parenthesized { expression, .. } => { Self::find_identifier_in_expr(expression, offset) @@ -458,8 +463,8 @@ impl SimpleLanguageService { } } Expression::Block(block) => { - for expr in &block.body { - Self::collect_identifiers(expr, name, results); + for stmt in &block.body { + Self::collect_identifiers(&stmt.expression, name, results); } } Expression::Return { value, .. } => { @@ -671,21 +676,21 @@ impl LanguageService for SimpleLanguageService { let mut results = Vec::new(); for (file_path, fd) in &self.files { let mut spans = Vec::new(); - for expr in &fd.module.expressions { - Self::collect_identifiers(expr, &ident.name, &mut spans); + for stmt in &fd.module.expressions { + Self::collect_identifiers(&stmt.expression, &ident.name, &mut spans); } // Also search class method bodies for class in &fd.module.classes { for method in class.methods.iter().chain(class.class_methods.iter()) { - for expr in &method.body { - Self::collect_identifiers(expr, &ident.name, &mut spans); + for stmt in &method.body { + Self::collect_identifiers(&stmt.expression, &ident.name, &mut spans); } } } // And standalone method bodies for smd in &fd.module.method_definitions { - for expr in &smd.method.body { - Self::collect_identifiers(expr, &ident.name, &mut spans); + for stmt in &smd.method.body { + Self::collect_identifiers(&stmt.expression, &ident.name, &mut spans); } } results.extend( diff --git a/crates/beamtalk-core/src/lint/cascade_candidate.rs b/crates/beamtalk-core/src/lint/cascade_candidate.rs index 0f3be82a4..c9413b292 100644 --- a/crates/beamtalk-core/src/lint/cascade_candidate.rs +++ b/crates/beamtalk-core/src/lint/cascade_candidate.rs @@ -21,7 +21,7 @@ //! because they may have side effects and are not straightforward to extract //! into a single cascade receiver. -use crate::ast::{Block, Expression, Identifier, Module}; +use crate::ast::{Block, Expression, ExpressionStatement, Identifier, Module}; use crate::lint::LintPass; use crate::source_analysis::Diagnostic; @@ -72,12 +72,12 @@ fn simple_receiver_name(expr: &Expression) -> Option<&str> { /// Check a flat sequence of statements for runs of 3+ consecutive sends to /// the same simple receiver, then recurse into nested expressions. -fn check_sequence(exprs: &[Expression], diagnostics: &mut Vec) { +fn check_sequence(exprs: &[ExpressionStatement], diagnostics: &mut Vec) { let mut i = 0; while i < exprs.len() { - if let Some(recv) = simple_receiver_name(&exprs[i]) { + if let Some(recv) = simple_receiver_name(&exprs[i].expression) { let run_start = i; - while i < exprs.len() && simple_receiver_name(&exprs[i]) == Some(recv) { + while i < exprs.len() && simple_receiver_name(&exprs[i].expression) == Some(recv) { i += 1; } let run_len = i - run_start; @@ -88,8 +88,8 @@ fn check_sequence(exprs: &[Expression], diagnostics: &mut Vec) { // logically-distinct operations and make test failures harder to // isolate. if run_len >= 3 && recv != "self" { - let first_span = exprs[run_start].span(); - let last_span = exprs[i - 1].span(); + let first_span = exprs[run_start].expression.span(); + let last_span = exprs[i - 1].expression.span(); let span = first_span.merge(last_span); let mut diag = Diagnostic::lint( format!( @@ -107,11 +107,11 @@ fn check_sequence(exprs: &[Expression], diagnostics: &mut Vec) { diagnostics.push(diag); } // Recurse into each expression in the run - for expr in &exprs[run_start..i] { - recurse(expr, diagnostics); + for stmt in &exprs[run_start..i] { + recurse(&stmt.expression, diagnostics); } } else { - recurse(&exprs[i], diagnostics); + recurse(&exprs[i].expression, diagnostics); i += 1; } } diff --git a/crates/beamtalk-core/src/lint/shadowed_block_param.rs b/crates/beamtalk-core/src/lint/shadowed_block_param.rs index 2d928d62b..4c39a8eaf 100644 --- a/crates/beamtalk-core/src/lint/shadowed_block_param.rs +++ b/crates/beamtalk-core/src/lint/shadowed_block_param.rs @@ -25,7 +25,7 @@ use std::collections::HashSet; -use crate::ast::{Block, Expression, MethodDefinition, Module, StringSegment}; +use crate::ast::{Block, Expression, ExpressionStatement, MethodDefinition, Module, StringSegment}; use crate::lint::LintPass; use crate::source_analysis::Diagnostic; @@ -114,9 +114,13 @@ fn check_method( /// Walk a sequence of expressions in order, collecting assignment targets into /// the current scope as they are encountered (so later blocks can see them). -fn check_expr_seq(exprs: &[Expression], scope: &mut LintScope, diagnostics: &mut Vec) { - for expr in exprs { - check_expr(expr, scope, diagnostics); +fn check_expr_seq( + exprs: &[ExpressionStatement], + scope: &mut LintScope, + diagnostics: &mut Vec, +) { + for stmt in exprs { + check_expr(&stmt.expression, scope, diagnostics); } } diff --git a/crates/beamtalk-core/src/lint/trailing_caret.rs b/crates/beamtalk-core/src/lint/trailing_caret.rs index 7be00f020..99630b3d9 100644 --- a/crates/beamtalk-core/src/lint/trailing_caret.rs +++ b/crates/beamtalk-core/src/lint/trailing_caret.rs @@ -38,11 +38,11 @@ impl LintPass for TrailingCaretPass { } fn check_method(method: &MethodDefinition, diagnostics: &mut Vec) { - let Some(last_expr) = method.body.last() else { + let Some(last_stmt) = method.body.last() else { return; }; - if let Expression::Return { span, .. } = last_expr { + if let Expression::Return { span, .. } = &last_stmt.expression { let method_name = method.selector.name(); let mut diag = Diagnostic::lint( format!( diff --git a/crates/beamtalk-core/src/lint/unnecessary_parens.rs b/crates/beamtalk-core/src/lint/unnecessary_parens.rs index 6121c1b2a..812256a16 100644 --- a/crates/beamtalk-core/src/lint/unnecessary_parens.rs +++ b/crates/beamtalk-core/src/lint/unnecessary_parens.rs @@ -34,8 +34,8 @@ pub(crate) struct UnnecessaryParensPass; impl LintPass for UnnecessaryParensPass { fn check(&self, module: &Module, diagnostics: &mut Vec) { for_each_expr_seq(module, |seq| { - for expr in seq { - check_expr(expr, diagnostics); + for stmt in seq { + check_expr(&stmt.expression, diagnostics); } }); } @@ -131,8 +131,8 @@ fn check_expr(expr: &Expression, diagnostics: &mut Vec) { } Expression::Block(Block { body, .. }) => { - for e in body { - check_expr(e, diagnostics); + for stmt in body { + check_expr(&stmt.expression, diagnostics); } } diff --git a/crates/beamtalk-core/src/queries/completion_provider.rs b/crates/beamtalk-core/src/queries/completion_provider.rs index 39637ccf6..4f4d2527e 100644 --- a/crates/beamtalk-core/src/queries/completion_provider.rs +++ b/crates/beamtalk-core/src/queries/completion_provider.rs @@ -241,7 +241,7 @@ fn detect_erlang_class_context(module: &Module, trimmed: &str, offset: u32) -> b /// Walks the AST to find a `ClassReference("Erlang")` expression near the cursor. fn find_erlang_class_ref(module: &Module, offset: u32) -> bool { - let all_exprs = module.expressions.iter().chain( + let all_exprs = module.expressions.iter().map(|s| &s.expression).chain( module .classes .iter() @@ -249,13 +249,13 @@ fn find_erlang_class_ref(module: &Module, offset: u32) -> bool { c.methods .iter() .chain(c.class_methods.iter()) - .flat_map(|m| m.body.iter()) + .flat_map(|m| m.body.iter().map(|s| &s.expression)) }) .chain( module .method_definitions .iter() - .flat_map(|smd| smd.method.body.iter()), + .flat_map(|smd| smd.method.body.iter().map(|s| &s.expression)), ), ); @@ -291,7 +291,7 @@ fn has_erlang_class_ref_at(expr: &Expression, offset: u32) -> bool { Expression::Block(block) => block .body .iter() - .any(|e| has_erlang_class_ref_at(e, offset)), + .any(|s| has_erlang_class_ref_at(&s.expression, offset)), Expression::Cascade { receiver, messages, .. } => { @@ -330,8 +330,8 @@ fn add_identifier_completions(module: &Module, completions: &mut Vec let mut identifiers = HashSet::new(); // Collect all identifiers from the module - for expr in &module.expressions { - collect_identifiers_from_expr(expr, &mut identifiers); + for stmt in &module.expressions { + collect_identifiers_from_expr(&stmt.expression, &mut identifiers); } // Add them as completions @@ -427,8 +427,8 @@ fn collect_identifiers_from_expr(expr: &Expression, identifiers: &mut HashSet { @@ -491,17 +491,18 @@ fn find_receiver_type(module: &Module, offset: u32, type_map: &TypeMap) -> Optio let expressions = module .expressions .iter() + .map(|s| &s.expression) .chain(module.classes.iter().flat_map(|c| { c.methods .iter() .chain(c.class_methods.iter()) - .flat_map(|m| m.body.iter()) + .flat_map(|m| m.body.iter().map(|s| &s.expression)) })) .chain( module .method_definitions .iter() - .flat_map(|smd| smd.method.body.iter()), + .flat_map(|smd| smd.method.body.iter().map(|s| &s.expression)), ); for expr in expressions { @@ -600,7 +601,7 @@ fn find_receiver_in_expr( Expression::Block(block) => block .body .iter() - .find_map(|e| find_receiver_in_expr(e, offset, type_map)), + .find_map(|s| find_receiver_in_expr(&s.expression, offset, type_map)), _ => None, } } diff --git a/crates/beamtalk-core/src/queries/definition_provider.rs b/crates/beamtalk-core/src/queries/definition_provider.rs index 38d97eb78..ae6a3ba49 100644 --- a/crates/beamtalk-core/src/queries/definition_provider.rs +++ b/crates/beamtalk-core/src/queries/definition_provider.rs @@ -38,8 +38,8 @@ use ecow::EcoString; /// matches `name`. Returns the span of the target identifier if found. #[must_use] pub fn find_definition_in_module(module: &Module, name: &str) -> Option { - for expr in &module.expressions { - if let Some(span) = find_definition_in_expr(expr, name) { + for stmt in &module.expressions { + if let Some(span) = find_definition_in_expr(&stmt.expression, name) { return Some(span); } } @@ -372,7 +372,7 @@ pub fn find_selector_lookup_in_expr(expr: &Expression, offset: u32) -> Option block .body .iter() - .find_map(|e| find_selector_lookup_in_expr(e, offset)), + .find_map(|s| find_selector_lookup_in_expr(&s.expression, offset)), Expression::Return { value, .. } => find_selector_lookup_in_expr(value, offset), Expression::Parenthesized { expression, .. } => { find_selector_lookup_in_expr(expression, offset) @@ -544,7 +544,7 @@ fn find_definition_in_expr(expr: &Expression, name: &str) -> Option { Expression::Block(block) => block .body .iter() - .find_map(|e| find_definition_in_expr(e, name)), + .find_map(|s| find_definition_in_expr(&s.expression, name)), _ => None, } } @@ -723,7 +723,7 @@ mod tests { let source = "obj at: 1 put: 2"; let module = parse_source(source); // The keyword "at:" starts at position 4 - let result = find_selector_in_expr(&module.expressions[0], 4); + let result = find_selector_in_expr(&module.expressions[0].expression, 4); assert!(result.is_some()); let (name, _span) = result.unwrap(); assert_eq!(name, "at:put:"); @@ -734,7 +734,7 @@ mod tests { let source = "obj at: 1 put: 2"; let module = parse_source(source); // Position 0 is on "obj" (receiver), not a selector - let result = find_selector_in_expr(&module.expressions[0], 0); + let result = find_selector_in_expr(&module.expressions[0].expression, 0); assert!(result.is_none()); } @@ -743,7 +743,7 @@ mod tests { let source = "obj size"; let module = parse_source(source); // Position 4 is on/near "size" - let result = find_selector_in_expr(&module.expressions[0], 4); + let result = find_selector_in_expr(&module.expressions[0].expression, 4); assert!(result.is_some()); let (name, _span) = result.unwrap(); assert_eq!(name, "size"); @@ -754,7 +754,7 @@ mod tests { let source = "3 + 4"; let module = parse_source(source); // Position 2 is on/near "+" - let result = find_selector_in_expr(&module.expressions[0], 2); + let result = find_selector_in_expr(&module.expressions[0].expression, 2); assert!(result.is_some()); let (name, _span) = result.unwrap(); assert_eq!(name, "+"); diff --git a/crates/beamtalk-core/src/queries/diagnostic_provider.rs b/crates/beamtalk-core/src/queries/diagnostic_provider.rs index 23d38d0a0..66c18e9eb 100644 --- a/crates/beamtalk-core/src/queries/diagnostic_provider.rs +++ b/crates/beamtalk-core/src/queries/diagnostic_provider.rs @@ -27,7 +27,7 @@ //! - DDD model: `docs/beamtalk-ddd-model.md` (Language Service Context) //! - LSP specification: Language Server Protocol publishDiagnostics notification -use crate::ast::{ExpectCategory, Expression, Module}; +use crate::ast::{ExpectCategory, Expression, ExpressionStatement, Module}; use crate::semantic_analysis; use crate::source_analysis::{Diagnostic, DiagnosticCategory, Span}; @@ -160,13 +160,13 @@ fn category_matches(expect_cat: ExpectCategory, diag_cat: Option, ) { - for (i, expr) in exprs.iter().enumerate() { - if let Expression::ExpectDirective { category, span } = expr { + for (i, stmt) in exprs.iter().enumerate() { + if let Expression::ExpectDirective { category, span } = &stmt.expression { if let Some(next) = exprs.get(i + 1) { - directives.push((*category, *span, next.span())); + directives.push((*category, *span, next.expression.span())); } else { // Trailing @expect with no following expression — treat as stale. // Use the directive's own span as the target span so it will diff --git a/crates/beamtalk-core/src/queries/hover_provider.rs b/crates/beamtalk-core/src/queries/hover_provider.rs index 70a1d8f66..dd7c11d2e 100644 --- a/crates/beamtalk-core/src/queries/hover_provider.rs +++ b/crates/beamtalk-core/src/queries/hover_provider.rs @@ -85,10 +85,14 @@ pub fn compute_hover( } // Find the expression at this position - for expr in &module.expressions { - if let Some(hover) = - find_hover_in_expr(expr, offset_val, &class_context, hierarchy, &type_map) - { + for stmt in &module.expressions { + if let Some(hover) = find_hover_in_expr( + &stmt.expression, + offset_val, + &class_context, + hierarchy, + &type_map, + ) { return Some(hover); } } @@ -99,10 +103,14 @@ pub fn compute_hover( if let Some(hover) = find_hover_on_method_signature(method, source, offset_val) { return Some(hover); } - for body_expr in &method.body { - if let Some(hover) = - find_hover_in_expr(body_expr, offset_val, &class_context, hierarchy, &type_map) - { + for body_stmt in &method.body { + if let Some(hover) = find_hover_in_expr( + &body_stmt.expression, + offset_val, + &class_context, + hierarchy, + &type_map, + ) { return Some(hover); } } @@ -111,10 +119,14 @@ pub fn compute_hover( if let Some(hover) = find_hover_on_method_signature(method, source, offset_val) { return Some(hover); } - for body_expr in &method.body { - if let Some(hover) = - find_hover_in_expr(body_expr, offset_val, &class_context, hierarchy, &type_map) - { + for body_stmt in &method.body { + if let Some(hover) = find_hover_in_expr( + &body_stmt.expression, + offset_val, + &class_context, + hierarchy, + &type_map, + ) { return Some(hover); } } @@ -126,10 +138,14 @@ pub fn compute_hover( if let Some(hover) = find_hover_on_method_signature(&smd.method, source, offset_val) { return Some(hover); } - for body_expr in &smd.method.body { - if let Some(hover) = - find_hover_in_expr(body_expr, offset_val, &class_context, hierarchy, &type_map) - { + for body_stmt in &smd.method.body { + if let Some(hover) = find_hover_in_expr( + &body_stmt.expression, + offset_val, + &class_context, + hierarchy, + &type_map, + ) { return Some(hover); } } @@ -365,7 +381,7 @@ fn selector_span_in_method_signature(method: &MethodDefinition, source: &str) -> let header_end_u32 = method .body .first() - .map_or(method.span.end(), |expr| expr.span().start()); + .map_or(method.span.end(), |stmt| stmt.expression.span().start()); let header_end = usize::try_from(header_end_u32).ok()?.min(source.len()); if method_start >= header_end { return None; @@ -576,7 +592,7 @@ fn find_hover_in_expr( Expression::Block(block) => block .body .iter() - .find_map(|expr| find_hover_in_expr(expr, offset, context, hierarchy, type_map)), + .find_map(|s| find_hover_in_expr(&s.expression, offset, context, hierarchy, type_map)), Expression::Return { value, .. } => { find_hover_in_expr(value, offset, context, hierarchy, type_map) } diff --git a/crates/beamtalk-core/src/queries/references_provider.rs b/crates/beamtalk-core/src/queries/references_provider.rs index 52b271f58..52e48dfa8 100644 --- a/crates/beamtalk-core/src/queries/references_provider.rs +++ b/crates/beamtalk-core/src/queries/references_provider.rs @@ -66,23 +66,23 @@ pub fn find_class_references<'a>( } // Expressions: identifiers and class references - for expr in &module.expressions { - collect_class_refs(expr, class_name, file_path, &mut results); + for stmt in &module.expressions { + collect_class_refs(&stmt.expression, class_name, file_path, &mut results); } // Class method bodies for class in &module.classes { for method in class.methods.iter().chain(class.class_methods.iter()) { - for expr in &method.body { - collect_class_refs(expr, class_name, file_path, &mut results); + for stmt in &method.body { + collect_class_refs(&stmt.expression, class_name, file_path, &mut results); } } } // Standalone method bodies for smd in &module.method_definitions { - for expr in &smd.method.body { - collect_class_refs(expr, class_name, file_path, &mut results); + for stmt in &smd.method.body { + collect_class_refs(&stmt.expression, class_name, file_path, &mut results); } } } @@ -119,8 +119,8 @@ fn collect_class_refs( } } Expression::Block(block) => { - for expr in &block.body { - collect_class_refs(expr, class_name, file_path, results); + for stmt in &block.body { + collect_class_refs(&stmt.expression, class_name, file_path, results); } } Expression::Return { value, .. } => { @@ -203,23 +203,23 @@ pub fn find_selector_references<'a>( } // Message sends and cascades in expressions - for expr in &module.expressions { - collect_selector_refs(expr, selector_name, file_path, &mut results); + for stmt in &module.expressions { + collect_selector_refs(&stmt.expression, selector_name, file_path, &mut results); } // Message sends and cascades in class method bodies for class in &module.classes { for method in class.methods.iter().chain(class.class_methods.iter()) { - for expr in &method.body { - collect_selector_refs(expr, selector_name, file_path, &mut results); + for stmt in &method.body { + collect_selector_refs(&stmt.expression, selector_name, file_path, &mut results); } } } // Message sends and cascades in standalone method bodies for smd in &module.method_definitions { - for expr in &smd.method.body { - collect_selector_refs(expr, selector_name, file_path, &mut results); + for stmt in &smd.method.body { + collect_selector_refs(&stmt.expression, selector_name, file_path, &mut results); } } } @@ -285,8 +285,8 @@ fn collect_selector_refs( collect_selector_refs(value, selector_name, file_path, results); } Expression::Block(block) => { - for expr in &block.body { - collect_selector_refs(expr, selector_name, file_path, results); + for stmt in &block.body { + collect_selector_refs(&stmt.expression, selector_name, file_path, results); } } Expression::Return { value, .. } => { diff --git a/crates/beamtalk-core/src/queries/signature_help_provider.rs b/crates/beamtalk-core/src/queries/signature_help_provider.rs index 3c104d184..3139bbcd0 100644 --- a/crates/beamtalk-core/src/queries/signature_help_provider.rs +++ b/crates/beamtalk-core/src/queries/signature_help_provider.rs @@ -56,9 +56,11 @@ pub fn compute_signature_help( let type_map = infer_types(module, hierarchy); // Search top-level expressions - for expr in &module.expressions { + for stmt in &module.expressions { let context = SigHelpClassContext::TopLevel; - if let Some(help) = find_signature_in_expr(expr, offset, &context, hierarchy, &type_map) { + if let Some(help) = + find_signature_in_expr(&stmt.expression, offset, &context, hierarchy, &type_map) + { return Some(help); } } @@ -67,9 +69,9 @@ pub fn compute_signature_help( for class in &module.classes { for method in &class.methods { let context = SigHelpClassContext::InstanceMethod(class); - for expr in &method.body { + for stmt in &method.body { if let Some(help) = - find_signature_in_expr(expr, offset, &context, hierarchy, &type_map) + find_signature_in_expr(&stmt.expression, offset, &context, hierarchy, &type_map) { return Some(help); } @@ -77,9 +79,9 @@ pub fn compute_signature_help( } for method in &class.class_methods { let context = SigHelpClassContext::ClassMethod(class); - for expr in &method.body { + for stmt in &method.body { if let Some(help) = - find_signature_in_expr(expr, offset, &context, hierarchy, &type_map) + find_signature_in_expr(&stmt.expression, offset, &context, hierarchy, &type_map) { return Some(help); } @@ -94,8 +96,9 @@ pub fn compute_signature_help( } else { SigHelpClassContext::StandaloneInstanceMethod(smd.class_name.name.as_str()) }; - for expr in &smd.method.body { - if let Some(help) = find_signature_in_expr(expr, offset, &context, hierarchy, &type_map) + for stmt in &smd.method.body { + if let Some(help) = + find_signature_in_expr(&stmt.expression, offset, &context, hierarchy, &type_map) { return Some(help); } @@ -158,10 +161,9 @@ fn find_signature_in_expr( } None } - Expression::Block(block) => block - .body - .iter() - .find_map(|e| find_signature_in_expr(e, offset, context, hierarchy, type_map)), + Expression::Block(block) => block.body.iter().find_map(|s| { + find_signature_in_expr(&s.expression, offset, context, hierarchy, type_map) + }), Expression::Assignment { target, value, .. } => { find_signature_in_expr(target, offset, context, hierarchy, type_map) .or_else(|| find_signature_in_expr(value, offset, context, hierarchy, type_map)) diff --git a/crates/beamtalk-core/src/semantic_analysis/block_analyzer.rs b/crates/beamtalk-core/src/semantic_analysis/block_analyzer.rs index 7396feeb2..4ddd519ac 100644 --- a/crates/beamtalk-core/src/semantic_analysis/block_analyzer.rs +++ b/crates/beamtalk-core/src/semantic_analysis/block_analyzer.rs @@ -48,9 +48,9 @@ impl Analyser { let mut mutations = Vec::new(); // Analyse block body - for expr in &block.body { - self.collect_captures_and_mutations(expr, &mut captures, &mut mutations); - self.analyse_expression(expr, None); + for stmt in &block.body { + self.collect_captures_and_mutations(&stmt.expression, &mut captures, &mut mutations); + self.analyse_expression(&stmt.expression, None); } // Store block info before emitting diagnostics (avoids unnecessary clones) diff --git a/crates/beamtalk-core/src/semantic_analysis/class_hierarchy/mod.rs b/crates/beamtalk-core/src/semantic_analysis/class_hierarchy/mod.rs index 1b6fbcde1..337fbc2e2 100644 --- a/crates/beamtalk-core/src/semantic_analysis/class_hierarchy/mod.rs +++ b/crates/beamtalk-core/src/semantic_analysis/class_hierarchy/mod.rs @@ -1109,7 +1109,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, _diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1181,7 +1181,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1202,7 +1202,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); @@ -1224,7 +1224,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); @@ -1247,7 +1247,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1266,7 +1266,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build(&module); assert_eq!(diags.len(), 1); @@ -1280,7 +1280,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1298,7 +1298,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build_with_options(&module, true); let h = h.unwrap(); @@ -1317,7 +1317,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build_with_options(&module, false); let h = h.unwrap(); @@ -1336,7 +1336,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build_with_options(&module, true); assert_eq!(diags.len(), 1); @@ -1448,7 +1448,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1472,7 +1472,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build(&module); assert!(diags.is_empty()); @@ -1490,7 +1490,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1512,7 +1512,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1534,7 +1534,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1556,7 +1556,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); let methods = h.all_methods("Counter"); @@ -1684,7 +1684,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1704,7 +1704,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -1768,7 +1768,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build(&module); @@ -1826,7 +1826,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build(&module); @@ -1881,7 +1881,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (_, diags) = ClassHierarchy::build(&module); @@ -1900,7 +1900,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); assert!( @@ -1922,7 +1922,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); @@ -1947,7 +1947,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); @@ -1969,7 +1969,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); @@ -2039,7 +2039,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); let method = hierarchy @@ -2087,7 +2087,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let hierarchy = ClassHierarchy::build(&module).0.unwrap(); let method = hierarchy @@ -2131,7 +2131,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -2149,7 +2149,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); assert_eq!(h.state_field_type("Counter", "label"), None); @@ -2162,7 +2162,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); assert_eq!(h.state_field_type("Counter", "nonexistent"), None); @@ -2202,7 +2202,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (h, diags) = ClassHierarchy::build(&module); let h = h.unwrap(); @@ -2259,7 +2259,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let h = ClassHierarchy::build(&module).0.unwrap(); @@ -2440,7 +2440,7 @@ mod tests { method_definitions: vec![], expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let (Ok(h), _) = ClassHierarchy::build(&module) else { panic!("build should succeed"); diff --git a/crates/beamtalk-core/src/semantic_analysis/method_validators.rs b/crates/beamtalk-core/src/semantic_analysis/method_validators.rs index b25bff9b4..6f32235b8 100644 --- a/crates/beamtalk-core/src/semantic_analysis/method_validators.rs +++ b/crates/beamtalk-core/src/semantic_analysis/method_validators.rs @@ -665,7 +665,7 @@ impl MethodValidator for TypeAwareStringArgValidator { mod tests { //! Tests for method-specific semantic validators (responds-to, inst-var-at, primitives, mutations). use super::*; - use crate::ast::{Block, BlockParameter, Identifier, KeywordPart}; + use crate::ast::{Block, BlockParameter, ExpressionStatement, Identifier, KeywordPart}; use crate::semantic_analysis::test_helpers::test_span; use crate::source_analysis::Span; @@ -1083,7 +1083,10 @@ mod tests { .collect(); Expression::Block(Block::new( params, - vec![Expression::Literal(Literal::Integer(1), test_span())], + vec![ExpressionStatement::bare(Expression::Literal( + Literal::Integer(1), + test_span(), + ))], test_span(), )) } diff --git a/crates/beamtalk-core/src/semantic_analysis/mod.rs b/crates/beamtalk-core/src/semantic_analysis/mod.rs index 7e682bd8a..18742ebcc 100644 --- a/crates/beamtalk-core/src/semantic_analysis/mod.rs +++ b/crates/beamtalk-core/src/semantic_analysis/mod.rs @@ -324,8 +324,8 @@ impl Analyser { // No need to re-define them here. // Analyse top-level expressions - for expr in &module.expressions { - self.analyse_expression(expr, None); + for stmt in &module.expressions { + self.analyse_expression(&stmt.expression, None); } // Analyse classes @@ -376,8 +376,8 @@ impl Analyser { } // Analyse method body - for expr in &method.body { - self.analyse_expression(expr, None); + for stmt in &method.body { + self.analyse_expression(&stmt.expression, None); } self.scope.pop(); // Exit method scope @@ -619,11 +619,15 @@ mod tests { use super::*; use crate::ast::{ Block, BlockParameter, ClassDefinition, ClassKind, CommentAttachment, Expression, - Identifier, Literal, MatchArm, MessageSelector, MethodDefinition, Pattern, - StateDeclaration, StringSegment, + ExpressionStatement, Identifier, Literal, MatchArm, MessageSelector, MethodDefinition, + Pattern, StateDeclaration, StringSegment, }; use crate::source_analysis::{Severity, Span}; + fn bare(expr: Expression) -> ExpressionStatement { + ExpressionStatement::bare(expr) + } + #[test] fn test_analyse_empty_module() { let module = Module::new(vec![], Span::default()); @@ -728,11 +732,14 @@ mod tests { // Create a simple block: [:x | x + 1] let block = Block::new( vec![BlockParameter::new("x", test_span())], - vec![Expression::Identifier(Identifier::new("x", test_span()))], + vec![bare(Expression::Identifier(Identifier::new( + "x", + test_span(), + )))], test_span(), ); let expr = Expression::Block(block); - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse(&module); @@ -758,14 +765,17 @@ mod tests { let block = Block::new( vec![BlockParameter::new("x", test_span())], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "count", test_span(), - ))], + )))], Span::new(10, 20), ); - let module = Module::new(vec![count_def, Expression::Block(block)], test_span()); + let module = Module::new( + vec![bare(count_def), bare(Expression::Block(block))], + test_span(), + ); let result = analyse(&module); @@ -782,17 +792,17 @@ mod tests { let block = Block::new( vec![BlockParameter::new("x", test_span())], vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new("temp", test_span()))), value: Box::new(Expression::Identifier(Identifier::new("x", test_span()))), span: test_span(), - }, - Expression::Identifier(Identifier::new("temp", test_span())), + }), + bare(Expression::Identifier(Identifier::new("temp", test_span()))), ], Span::new(10, 20), ); - let module = Module::new(vec![Expression::Block(block)], test_span()); + let module = Module::new(vec![bare(Expression::Block(block))], test_span()); let result = analyse(&module); @@ -823,18 +833,21 @@ mod tests { let block = Block::new( vec![BlockParameter::new("x", test_span())], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "count", test_span(), ))), value: Box::new(Expression::Identifier(Identifier::new("x", test_span()))), span: test_span(), - }], + })], Span::new(10, 20), ); - let module = Module::new(vec![count_def, Expression::Block(block)], test_span()); + let module = Module::new( + vec![bare(count_def), bare(Expression::Block(block))], + test_span(), + ); let result = analyse(&module); @@ -853,14 +866,14 @@ mod tests { // Create: 5 timesRepeat: [x := 1] let block = Block::new( vec![], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new("x", test_span()))), value: Box::new(Expression::Literal( crate::ast::Literal::Integer(1), test_span(), )), span: test_span(), - }], + })], Span::new(20, 30), ); @@ -878,7 +891,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![message_send], test_span()); + let module = Module::new(vec![bare(message_send)], test_span()); let result = analyse(&module); @@ -896,10 +909,10 @@ mod tests { // Code: myBlock := [:x | x + 1] let block = Block::new( vec![BlockParameter::new("x", Span::new(15, 16))], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "x", Span::new(19, 20), - ))], + )))], Span::new(12, 25), ); @@ -912,7 +925,7 @@ mod tests { span: Span::new(0, 25), }; - let module = Module::new(vec![assignment], Span::new(0, 25)); + let module = Module::new(vec![bare(assignment)], Span::new(0, 25)); let result = analyse(&module); // Block should have Stored context @@ -927,10 +940,10 @@ mod tests { // Code: array at: 1 put: [:x | x + 1] let block = Block::new( vec![BlockParameter::new("x", Span::new(23, 24))], - vec![Expression::Identifier(Identifier::new( + vec![bare(Expression::Identifier(Identifier::new( "x", Span::new(27, 28), - ))], + )))], Span::new(20, 33), ); @@ -951,7 +964,7 @@ mod tests { span: Span::new(0, 33), }; - let module = Module::new(vec![message], Span::new(0, 33)); + let module = Module::new(vec![bare(message)], Span::new(0, 33)); let result = analyse(&module); // Block should have Passed context @@ -977,7 +990,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'value' only, not 'x' @@ -1007,7 +1020,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'value' only, not 'x' (used in guard and body) @@ -1041,7 +1054,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'result' only, not 'value' (pattern-bound) @@ -1092,7 +1105,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'result' only, not 'value' or 'msg' (pattern-bound) @@ -1124,7 +1137,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'list' only, not 'head' or 'tail' (pattern-bound) @@ -1160,7 +1173,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for 'value' only, not 'x' or 'y' (pattern-bound in separate arms) @@ -1189,7 +1202,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have 2 diagnostics: value and undefined_var @@ -1219,7 +1232,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should have diagnostic for undefined_var in guard @@ -1249,7 +1262,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should only have diagnostic for 'value', not 'x' @@ -1290,7 +1303,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![match_expr], test_span()); + let module = Module::new(vec![bare(match_expr)], test_span()); let result = analyse(&module); // Should only error on 'result', not 'x' or 'y' @@ -1316,11 +1329,11 @@ mod tests { let get_value_method = MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::FieldAccess { + body: vec![bare(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new("self", test_span()))), field: Identifier::new("value", test_span()), span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -1358,7 +1371,7 @@ mod tests { classes: vec![class_def], method_definitions: Vec::new(), expressions: vec![], - leading_comments: vec![], + file_leading_comments: vec![], span: test_span(), }; let result = analyse(&module); @@ -1388,7 +1401,7 @@ mod tests { let block = Expression::Block(crate::ast::Block { parameters: vec![], - body: vec![field_assignment], + body: vec![bare(field_assignment)], span: test_span(), }); @@ -1402,7 +1415,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![assignment], test_span()); + let module = Module::new(vec![bare(assignment)], test_span()); let result = analyse(&module); // Should have at least 1 error diagnostic for field assignment in stored block @@ -1435,7 +1448,7 @@ mod tests { let block = Expression::Block(crate::ast::Block { parameters: vec![crate::ast::BlockParameter::new("x", test_span())], - body: vec![field_assignment], + body: vec![bare(field_assignment)], span: test_span(), }); @@ -1451,7 +1464,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![message_send], test_span()); + let module = Module::new(vec![bare(message_send)], test_span()); let result = analyse(&module); // Should have at least 1 error diagnostic for field assignment in passed block @@ -1503,7 +1516,7 @@ mod tests { let block = Expression::Block(crate::ast::Block { parameters: vec![], - body: vec![count_mutation], + body: vec![bare(count_mutation)], span: test_span(), }); @@ -1517,7 +1530,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![count_def, block_assignment], test_span()); + let module = Module::new(vec![bare(count_def), bare(block_assignment)], test_span()); let result = analyse(&module); // Should have NO diagnostic — captured variable mutations in stored blocks are valid @@ -1544,7 +1557,7 @@ mod tests { let block = Expression::Block(crate::ast::Block { parameters: vec![], - body: vec![field_assignment], + body: vec![bare(field_assignment)], span: test_span(), }); @@ -1560,7 +1573,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![message_send], test_span()); + let module = Module::new(vec![bare(message_send)], test_span()); let result = analyse(&module); // Should have NO diagnostics for field assignment in control flow blocks @@ -1600,7 +1613,7 @@ mod tests { let block = Expression::Block(crate::ast::Block { parameters: vec![], - body: vec![x_def, x_mutation], + body: vec![bare(x_def), bare(x_mutation)], span: test_span(), }); @@ -1614,7 +1627,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![block_assignment], test_span()); + let module = Module::new(vec![bare(block_assignment)], test_span()); let result = analyse(&module); // Should have NO diagnostics - local variables can be mutated @@ -1632,7 +1645,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); // Without known vars - should report undefined let result_without = analyse(&module); @@ -1671,7 +1684,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); // With 'x' known, the RHS reference should not report undefined let result = analyse_with_known_vars(&module, &["x"]); @@ -1744,7 +1757,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -1783,7 +1796,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -1820,7 +1833,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse_with_known_vars(&module, &["counter"]); // No symbol-related diagnostics @@ -1854,7 +1867,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse_with_known_vars(&module, &["counter"]); let symbol_errors: Vec<_> = result @@ -1905,7 +1918,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse(&module); let symbol_errors: Vec<_> = result @@ -1943,7 +1956,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse_with_known_vars(&module, &["obj"]); let symbol_errors: Vec<_> = result @@ -1982,7 +1995,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![expr], test_span()); + let module = Module::new(vec![bare(expr)], test_span()); let result = analyse_with_known_vars(&module, &["obj"]); assert!( @@ -2024,7 +2037,7 @@ mod tests { span: test_span(), }; - let module = Module::new(vec![cascade], test_span()); + let module = Module::new(vec![bare(cascade)], test_span()); let result = analyse_with_known_vars(&module, &["counter"]); let symbol_errors: Vec<_> = result @@ -2059,7 +2072,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("area".into()), parameters: vec![], - body: vec![Expression::Literal(Literal::Integer(42), test_span())], + body: vec![bare(Expression::Literal(Literal::Integer(42), test_span()))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2089,9 +2102,9 @@ mod tests { let module = Module { classes: vec![class], method_definitions: Vec::new(), - expressions: vec![spawn_expr], + expressions: vec![bare(spawn_expr)], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2117,7 +2130,7 @@ mod tests { fn test_self_outside_method_gives_specialized_error() { // Using self at module top level should give a specialized message let self_expr = Expression::Identifier(Identifier::new("self", Span::new(0, 4))); - let module = Module::new(vec![self_expr], test_span()); + let module = Module::new(vec![bare(self_expr)], test_span()); let result = analyse(&module); let self_errors: Vec<_> = result @@ -2156,14 +2169,14 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::FieldAccess { + body: vec![bare(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", test_span(), ))), field: Identifier::new("value", test_span()), span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2183,7 +2196,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2219,22 +2232,22 @@ mod tests { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(10, 11), ))), value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }, - Expression::FieldAccess { + }), + bare(Expression::FieldAccess { receiver: Box::new(Expression::Identifier(Identifier::new( "self", test_span(), ))), field: Identifier::new("value", test_span()), span: test_span(), - }, + }), ], return_type: None, is_sealed: false, @@ -2255,7 +2268,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2286,12 +2299,12 @@ mod tests { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new("x", test_span()))), value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }, - Expression::Identifier(Identifier::new("x", test_span())), + }), + bare(Expression::Identifier(Identifier::new("x", test_span()))), ], return_type: None, is_sealed: false, @@ -2312,7 +2325,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2338,11 +2351,11 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("doSomething".into()), parameters: vec![], - body: vec![Expression::Assignment { + body: vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new("_x", test_span()))), value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2362,7 +2375,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2395,7 +2408,7 @@ mod tests { name: Identifier::new("newValue", test_span()), type_annotation: None, }], - body: vec![Expression::Literal(Literal::Integer(0), test_span())], + body: vec![bare(Expression::Literal(Literal::Integer(0), test_span()))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2415,7 +2428,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2450,7 +2463,7 @@ mod tests { name: Identifier::new("_newValue", test_span()), type_annotation: None, }], - body: vec![Expression::Literal(Literal::Integer(0), test_span())], + body: vec![bare(Expression::Literal(Literal::Integer(0), test_span()))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2470,7 +2483,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2503,7 +2516,10 @@ mod tests { name: Identifier::new("x", test_span()), type_annotation: None, }], - body: vec![Expression::Identifier(Identifier::new("x", test_span()))], + body: vec![bare(Expression::Identifier(Identifier::new( + "x", + test_span(), + )))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2523,7 +2539,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2557,11 +2573,11 @@ mod tests { name: Identifier::new("index", test_span()), type_annotation: None, }], - body: vec![Expression::Primitive { + body: vec![bare(Expression::Primitive { name: "at:".into(), is_quoted: true, span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2580,7 +2596,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); let warnings: Vec<_> = result @@ -2616,11 +2632,11 @@ mod tests { name: Identifier::new("initArgs", test_span()), type_annotation: None, }], - body: vec![Expression::Primitive { + body: vec![bare(Expression::Primitive { name: "actorSpawnWith".into(), is_quoted: false, span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2639,7 +2655,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); let warnings: Vec<_> = result @@ -2669,15 +2685,15 @@ mod tests { selector: MessageSelector::Unary("create".into()), parameters: vec![], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "temp", Span::new(10, 14), ))), value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }, - Expression::Identifier(Identifier::new("nil", test_span())), + }), + bare(Expression::Identifier(Identifier::new("nil", test_span()))), ], return_type: None, is_sealed: false, @@ -2697,7 +2713,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2724,11 +2740,14 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Block(Block::new( + body: vec![bare(Expression::Block(Block::new( vec![BlockParameter::new("x", test_span())], - vec![Expression::Identifier(Identifier::new("x", test_span()))], + vec![bare(Expression::Identifier(Identifier::new( + "x", + test_span(), + )))], test_span(), - ))], + )))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2748,7 +2767,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2775,7 +2794,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Match { + body: vec![bare(Expression::Match { value: Box::new(Expression::Literal(Literal::Integer(1), test_span())), arms: vec![MatchArm::new( Pattern::Variable(Identifier::new("result", test_span())), @@ -2783,7 +2802,7 @@ mod tests { test_span(), )], span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2803,7 +2822,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2830,18 +2849,18 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Block(Block::new( + body: vec![bare(Expression::Block(Block::new( vec![], - vec![Expression::Assignment { + vec![bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "unused", Span::new(10, 16), ))), value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }], + })], test_span(), - ))], + )))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -2861,7 +2880,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2891,19 +2910,22 @@ mod tests { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], body: vec![ - Expression::Assignment { + bare(Expression::Assignment { target: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(10, 11), ))), value: Box::new(Expression::Literal(Literal::Integer(1), test_span())), span: test_span(), - }, - Expression::Block(Block::new( + }), + bare(Expression::Block(Block::new( vec![], - vec![Expression::Identifier(Identifier::new("x", test_span()))], + vec![bare(Expression::Identifier(Identifier::new( + "x", + test_span(), + )))], test_span(), - )), + ))), ], return_type: None, is_sealed: false, @@ -2924,7 +2946,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -2954,11 +2976,11 @@ mod tests { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], body: vec![ - Expression::Return { + bare(Expression::Return { value: Box::new(Expression::Literal(Literal::Integer(42), Span::new(0, 4))), span: Span::new(0, 4), - }, - Expression::MessageSend { + }), + bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "self", Span::new(5, 9), @@ -2967,7 +2989,7 @@ mod tests { arguments: vec![], is_cast: false, span: Span::new(5, 20), - }, + }), ], return_type: None, is_sealed: false, @@ -2988,7 +3010,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3019,7 +3041,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Literal(Literal::Integer(42), test_span())], + body: vec![bare(Expression::Literal(Literal::Integer(42), test_span()))], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3039,7 +3061,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3057,11 +3079,11 @@ mod tests { let block = Expression::Block(Block { parameters: vec![], body: vec![ - Expression::Return { + bare(Expression::Return { value: Box::new(Expression::Literal(Literal::Integer(42), Span::new(0, 4))), span: Span::new(0, 4), - }, - Expression::Literal(Literal::Integer(99), Span::new(5, 7)), + }), + bare(Expression::Literal(Literal::Integer(99), Span::new(5, 7))), ], span: test_span(), }); @@ -3078,7 +3100,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("test".into()), parameters: vec![], - body: vec![block], + body: vec![bare(block)], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3098,7 +3120,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3124,10 +3146,10 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("getValue".into()), parameters: vec![], - body: vec![Expression::Return { + body: vec![bare(Expression::Return { value: Box::new(Expression::Literal(Literal::Integer(42), test_span())), span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3147,7 +3169,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3165,7 +3187,7 @@ mod tests { fn test_super_outside_method_gives_error() { // Using super at module top level should error let super_expr = Expression::Super(Span::new(0, 5)); - let module = Module::new(vec![super_expr], test_span()); + let module = Module::new(vec![bare(super_expr)], test_span()); let result = analyse(&module); let super_errors: Vec<_> = result @@ -3196,13 +3218,13 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("reset".into()), parameters: vec![], - body: vec![Expression::MessageSend { + body: vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Super(test_span())), selector: MessageSelector::Unary("reset".into()), arguments: vec![], is_cast: false, span: test_span(), - }], + })], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3222,7 +3244,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3239,7 +3261,7 @@ mod tests { // super at class level (not inside method) should error // This tests depth 1 (class scope, not method scope) let super_expr = Expression::Super(Span::new(0, 5)); - let module = Module::new(vec![super_expr], test_span()); + let module = Module::new(vec![bare(super_expr)], test_span()); let result = analyse(&module); let super_errors: Vec<_> = result @@ -3260,7 +3282,7 @@ mod tests { name: "x".into(), span: Span::new(10, 11), }], - body: vec![Expression::MessageSend { + body: vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Identifier(Identifier::new( "x", Span::new(14, 15), @@ -3269,7 +3291,7 @@ mod tests { arguments: vec![Expression::Literal(Literal::Integer(1), Span::new(18, 19))], is_cast: false, span: Span::new(14, 19), - }], + })], span: Span::new(8, 20), }); @@ -3278,7 +3300,7 @@ mod tests { name: "x".into(), span: Span::new(1, 2), }], - body: vec![inner_block], + body: vec![bare(inner_block)], span: Span::new(0, 21), }); @@ -3294,7 +3316,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("test".into()), parameters: vec![], - body: vec![outer_block], + body: vec![bare(outer_block)], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3314,7 +3336,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3336,10 +3358,10 @@ mod tests { name: "_x".into(), span: Span::new(10, 12), }], - body: vec![Expression::Identifier(Identifier::new( + body: vec![bare(Expression::Identifier(Identifier::new( "_x", Span::new(15, 17), - ))], + )))], span: Span::new(8, 18), }); @@ -3348,7 +3370,7 @@ mod tests { name: "_x".into(), span: Span::new(1, 3), }], - body: vec![inner_block], + body: vec![bare(inner_block)], span: Span::new(0, 19), }); @@ -3363,7 +3385,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("test".into()), parameters: vec![], - body: vec![outer_block], + body: vec![bare(outer_block)], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3383,7 +3405,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3403,10 +3425,10 @@ mod tests { name: "y".into(), span: Span::new(10, 11), }], - body: vec![Expression::Identifier(Identifier::new( + body: vec![bare(Expression::Identifier(Identifier::new( "y", Span::new(14, 15), - ))], + )))], span: Span::new(8, 16), }); @@ -3415,7 +3437,7 @@ mod tests { name: "x".into(), span: Span::new(1, 2), }], - body: vec![inner_block], + body: vec![bare(inner_block)], span: Span::new(0, 17), }); @@ -3430,7 +3452,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("test".into()), parameters: vec![], - body: vec![outer_block], + body: vec![bare(outer_block)], return_type: None, is_sealed: false, kind: crate::ast::MethodKind::Primary, @@ -3450,7 +3472,7 @@ mod tests { method_definitions: Vec::new(), expressions: vec![], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3493,11 +3515,14 @@ mod tests { let block = Block::new( vec![BlockParameter::new("val", test_span())], - vec![match_expr], + vec![bare(match_expr)], block_span, ); - let module = Module::new(vec![outer_x, Expression::Block(block)], test_span()); + let module = Module::new( + vec![bare(outer_x), bare(Expression::Block(block))], + test_span(), + ); let result = analyse(&module); @@ -3544,11 +3569,14 @@ mod tests { let block = Block::new( vec![BlockParameter::new("val", test_span())], - vec![match_expr], + vec![bare(match_expr)], block_span, ); - let module = Module::new(vec![outer_y, Expression::Block(block)], test_span()); + let module = Module::new( + vec![bare(outer_y), bare(Expression::Block(block))], + test_span(), + ); let result = analyse(&module); @@ -3605,7 +3633,7 @@ mod tests { shape.class_methods.push(MethodDefinition { selector: MessageSelector::Unary("create".into()), parameters: vec![], - body: vec![make_spawn_expr("Shape")], + body: vec![bare(make_spawn_expr("Shape"))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -3619,7 +3647,7 @@ mod tests { method_definitions: Vec::new(), expressions: Vec::new(), span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3654,9 +3682,9 @@ mod tests { let module = Module { classes: vec![shape], method_definitions: Vec::new(), - expressions: vec![interp], + expressions: vec![bare(interp)], span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3688,7 +3716,7 @@ mod tests { method: MethodDefinition { selector: MessageSelector::Unary("build".into()), parameters: vec![], - body: vec![make_spawn_expr("Shape")], + body: vec![bare(make_spawn_expr("Shape"))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -3704,7 +3732,7 @@ mod tests { method_definitions: vec![standalone], expressions: Vec::new(), span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); @@ -3762,7 +3790,7 @@ mod tests { method: MethodDefinition { selector: MessageSelector::Unary("build".into()), parameters: vec![], - body: vec![new_expr], + body: vec![bare(new_expr)], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -3778,7 +3806,7 @@ mod tests { method_definitions: vec![standalone], expressions: Vec::new(), span: test_span(), - leading_comments: vec![], + file_leading_comments: vec![], }; let result = analyse(&module); diff --git a/crates/beamtalk-core/src/semantic_analysis/name_resolver.rs b/crates/beamtalk-core/src/semantic_analysis/name_resolver.rs index 488a9f279..4ee436a25 100644 --- a/crates/beamtalk-core/src/semantic_analysis/name_resolver.rs +++ b/crates/beamtalk-core/src/semantic_analysis/name_resolver.rs @@ -78,8 +78,8 @@ impl NameResolver { self.scope.define("nil", module.span, BindingKind::Local); // Resolve top-level expressions - for expr in &module.expressions { - self.resolve_expression(expr); + for stmt in &module.expressions { + self.resolve_expression(&stmt.expression); } // Resolve classes @@ -161,7 +161,10 @@ impl NameResolver { // parameters are forwarded implicitly to the underlying Erlang function; // none of them appear as identifiers in the AST, so the normal // "never referenced" heuristic produces false positives. - let is_primitive_body = matches!(method.body.as_slice(), [Expression::Primitive { .. }]); + let is_primitive_body = matches!( + method.body.as_slice(), + [s] if matches!(s.expression, Expression::Primitive { .. }) + ); if !is_primitive_body { self.collect_unused_param_warnings(); } @@ -394,11 +397,12 @@ impl NameResolver { /// Iterates through expressions, resolving each one. If a `Return` expression /// is encountered and there are subsequent expressions, emits a warning for the /// first unreachable expression only (avoids diagnostic spam). - fn resolve_body(&mut self, body: &[Expression]) { + fn resolve_body(&mut self, body: &[crate::ast::ExpressionStatement]) { let mut saw_return = false; let mut warned = false; - for expr in body { + for stmt in body { + let expr = &stmt.expression; if saw_return && !warned { // First unreachable expression after early return — warn once let mut diag = diff --git a/crates/beamtalk-core/src/semantic_analysis/primitive_validator.rs b/crates/beamtalk-core/src/semantic_analysis/primitive_validator.rs index cace38d63..0e998b86d 100644 --- a/crates/beamtalk-core/src/semantic_analysis/primitive_validator.rs +++ b/crates/beamtalk-core/src/semantic_analysis/primitive_validator.rs @@ -87,8 +87,8 @@ pub fn validate_primitives(module: &Module, options: &CompilerOptions) -> Vec Vec { - for body_expr in &block.body { - validate_expr(body_expr, is_stdlib, options, diagnostics); + for body_stmt in &block.body { + validate_expr(&body_stmt.expression, is_stdlib, options, diagnostics); } } Expression::Return { value, .. } diff --git a/crates/beamtalk-core/src/semantic_analysis/type_checker.rs b/crates/beamtalk-core/src/semantic_analysis/type_checker.rs index e3ac08eca..d1120f345 100644 --- a/crates/beamtalk-core/src/semantic_analysis/type_checker.rs +++ b/crates/beamtalk-core/src/semantic_analysis/type_checker.rs @@ -119,8 +119,8 @@ impl TypeChecker { let mut env = TypeEnv::new(); // Check top-level expressions - for expr in &module.expressions { - self.infer_expr(expr, hierarchy, &mut env, false); + for stmt in &module.expressions { + self.infer_expr(&stmt.expression, hierarchy, &mut env, false); } // Check method bodies inside class definitions @@ -135,7 +135,8 @@ impl TypeChecker { method_env.set("self", InferredType::Known(class.name.name.clone())); Self::set_param_types(&mut method_env, &method.parameters); let mut body_type = InferredType::Dynamic; - for expr in &method.body { + for stmt in &method.body { + let expr = &stmt.expression; body_type = self.infer_expr(expr, hierarchy, &mut method_env, is_abstract); if matches!(expr, Expression::Return { .. }) { break; // Explicit return ends the body; later expressions are unreachable @@ -153,7 +154,8 @@ impl TypeChecker { method_env.set("self", InferredType::Known(class.name.name.clone())); Self::set_param_types(&mut method_env, &method.parameters); let mut body_type = InferredType::Dynamic; - for expr in &method.body { + for stmt in &method.body { + let expr = &stmt.expression; body_type = self.infer_expr(expr, hierarchy, &mut method_env, is_abstract); if matches!(expr, Expression::Return { .. }) { break; @@ -178,7 +180,8 @@ impl TypeChecker { method_env.set("self", InferredType::Known(class_name.clone())); Self::set_param_types(&mut method_env, &standalone.method.parameters); let mut body_type = InferredType::Dynamic; - for expr in &standalone.method.body { + for stmt in &standalone.method.body { + let expr = &stmt.expression; body_type = self.infer_expr(expr, hierarchy, &mut method_env, is_abstract); if matches!(expr, Expression::Return { .. }) { break; @@ -358,8 +361,13 @@ impl TypeChecker { for param in &block.parameters { block_env.set(param.name.as_str(), InferredType::Dynamic); } - for body_expr in &block.body { - self.infer_expr(body_expr, hierarchy, &mut block_env, in_abstract_method); + for body_stmt in &block.body { + self.infer_expr( + &body_stmt.expression, + hierarchy, + &mut block_env, + in_abstract_method, + ); } InferredType::Known("Block".into()) } @@ -621,7 +629,7 @@ impl TypeChecker { if method .body .iter() - .any(|e| matches!(e, Expression::Primitive { .. })) + .any(|s| matches!(s.expression, Expression::Primitive { .. })) { return; } @@ -730,7 +738,7 @@ impl TypeChecker { if method .body .iter() - .any(|e| matches!(e, Expression::Primitive { .. })) + .any(|s| matches!(s.expression, Expression::Primitive { .. })) { return; } @@ -1106,9 +1114,9 @@ mod tests { //! Tests for zero-syntax type inference across all expression forms. use super::*; use crate::ast::{ - Block, CascadeMessage, ClassDefinition, ClassKind, CommentAttachment, Identifier, - KeywordPart, MethodDefinition, MethodKind, Module, ParameterDefinition, StateDeclaration, - TypeAnnotation, + Block, CascadeMessage, ClassDefinition, ClassKind, CommentAttachment, ExpressionStatement, + Identifier, KeywordPart, MethodDefinition, MethodKind, Module, ParameterDefinition, + StateDeclaration, TypeAnnotation, }; use crate::source_analysis::Span; @@ -1123,15 +1131,31 @@ mod tests { } } + fn bare(expr: Expression) -> ExpressionStatement { + ExpressionStatement::bare(expr) + } + fn make_module(expressions: Vec) -> Module { - Module::new(expressions, span()) + Module::new( + expressions + .into_iter() + .map(ExpressionStatement::bare) + .collect(), + span(), + ) } fn make_module_with_classes( expressions: Vec, classes: Vec, ) -> Module { - let mut module = Module::new(expressions, span()); + let mut module = Module::new( + expressions + .into_iter() + .map(ExpressionStatement::bare) + .collect(), + span(), + ); module.classes = classes; module } @@ -1506,7 +1530,7 @@ mod tests { let block_expr = Expression::Block(Block { parameters: vec![], - body: vec![int_lit(42)], + body: vec![bare(int_lit(42))], span: span(), }); @@ -1640,11 +1664,11 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("greet".into()), parameters: vec![], - body: vec![msg_send( + body: vec![bare(msg_send( var("self"), MessageSelector::Unary("nonExistent".into()), vec![], - )], + ))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -1735,7 +1759,7 @@ mod tests { let type_map = infer_types(&module, &hierarchy); // The integer literal should be recorded as Integer - let ty = type_map.get(module.expressions[0].span()); + let ty = type_map.get(module.expressions[0].expression.span()); assert!(ty.is_some(), "TypeMap should record literal type"); assert_eq!( ty.unwrap(), @@ -1753,7 +1777,7 @@ mod tests { // The second expression (var "x") should be recorded as Integer let x_expr = &module.expressions[1]; - let ty = type_map.get(x_expr.span()); + let ty = type_map.get(x_expr.expression.span()); assert!( ty.is_some(), "TypeMap should record variable type after assignment" @@ -1770,7 +1794,7 @@ mod tests { let module = make_module(vec![str_lit("hello")]); let hierarchy = ClassHierarchy::with_builtins(); let type_map = infer_types(&module, &hierarchy); - let ty = type_map.get(module.expressions[0].span()); + let ty = type_map.get(module.expressions[0].expression.span()); assert_eq!( ty, Some(&InferredType::Known("String".into())), @@ -1806,7 +1830,7 @@ mod tests { MethodDefinition { selector: MessageSelector::Unary(selector.into()), parameters: vec![], - body, + body: body.into_iter().map(ExpressionStatement::bare).collect(), return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -1964,7 +1988,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("reset".into()), parameters: vec![], - body: vec![int_lit(0)], + body: vec![bare(int_lit(0))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -1992,13 +2016,13 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("reset".into()), parameters: vec![], - body: vec![Expression::MessageSend { + body: vec![bare(Expression::MessageSend { receiver: Box::new(Expression::Super(super_span)), selector: MessageSelector::Unary("reset".into()), arguments: vec![], is_cast: false, span: msg_span, - }], + })], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2041,7 +2065,7 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("reset".into()), parameters: vec![], - body: vec![int_lit(0)], + body: vec![bare(int_lit(0))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2067,11 +2091,11 @@ mod tests { methods: vec![MethodDefinition { selector: MessageSelector::Unary("test".into()), parameters: vec![], - body: vec![msg_send( + body: vec![bare(msg_send( Expression::Super(span()), MessageSelector::Unary("nonExistent".into()), vec![], - )], + ))], return_type: None, is_sealed: false, kind: MethodKind::Primary, @@ -2290,7 +2314,7 @@ mod tests { vec![MethodDefinition::new( MessageSelector::Keyword(vec![KeywordPart::new("deposit:", span())]), vec![ParameterDefinition::new(ident("amount"))], // no type annotation - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2325,7 +2349,7 @@ mod tests { vec![MethodDefinition::new( MessageSelector::Unary("increment".into()), vec![], - vec![int_lit(1)], + vec![bare(int_lit(1))], span(), )], span(), @@ -2358,7 +2382,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Integer")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], TypeAnnotation::Simple(ident("Integer")), span(), )], @@ -2392,7 +2416,7 @@ mod tests { vec![MethodDefinition::new( MessageSelector::Keyword(vec![KeywordPart::new("deposit:", span())]), vec![ParameterDefinition::new(ident("amount"))], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2424,11 +2448,11 @@ mod tests { vec![MethodDefinition::new( MessageSelector::Binary("+".into()), vec![ParameterDefinition::new(ident("other"))], - vec![Expression::Primitive { + vec![bare(Expression::Primitive { name: "+".into(), is_quoted: true, span: span(), - }], + })], span(), )], span(), @@ -2552,7 +2576,7 @@ mod tests { vec![MethodDefinition::with_return_type( MessageSelector::Unary("getBalance".into()), vec![], - vec![str_lit("oops")], // Returns String, declared Integer + vec![bare(str_lit("oops"))], // Returns String, declared Integer TypeAnnotation::Simple(ident("Integer")), span(), )], @@ -2588,7 +2612,7 @@ mod tests { vec![MethodDefinition::with_return_type( MessageSelector::Unary("getBalance".into()), vec![], - vec![int_lit(42)], + vec![bare(int_lit(42))], TypeAnnotation::Simple(ident("Integer")), span(), )], @@ -2621,11 +2645,11 @@ mod tests { vec![MethodDefinition::with_return_type( MessageSelector::Unary("value".into()), vec![], - vec![Expression::Primitive { + vec![bare(Expression::Primitive { name: "value".into(), is_quoted: true, span: span(), - }], + })], TypeAnnotation::Simple(ident("Integer")), span(), )], @@ -2658,7 +2682,7 @@ mod tests { vec![MethodDefinition::new( MessageSelector::Unary("count".into()), vec![], - vec![str_lit("oops")], + vec![bare(str_lit("oops"))], span(), )], span(), @@ -2716,7 +2740,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Integer")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2772,7 +2796,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Integer")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2826,7 +2850,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Number")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2843,7 +2867,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("String")), )], - vec![str_lit("ok")], + vec![bare(str_lit("ok"))], span(), )], span(), @@ -2880,7 +2904,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Number")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2897,7 +2921,7 @@ mod tests { ident("amount"), TypeAnnotation::Simple(ident("Integer")), )], - vec![int_lit(0)], + vec![bare(int_lit(0))], span(), )], span(), @@ -2929,7 +2953,7 @@ mod tests { vec![MethodDefinition::with_return_type( MessageSelector::Unary("getBalance".into()), vec![], - vec![str_lit("oops")], + vec![bare(str_lit("oops"))], TypeAnnotation::Simple(ident("Integer")), span(), )], @@ -3114,7 +3138,7 @@ mod tests { vec![MethodDefinition::with_return_type( MessageSelector::Unary("compute".into()), vec![], - vec![int_lit(42)], // Integer is subtype of Number + vec![bare(int_lit(42))], // Integer is subtype of Number TypeAnnotation::Simple(ident("Number")), span(), )], @@ -3174,11 +3198,11 @@ mod tests { MessageSelector::Unary("compute".into()), vec![], vec![ - Expression::Return { + bare(Expression::Return { value: Box::new(int_lit(42)), span: span(), - }, - str_lit("unreachable"), // would be String, but never reached + }), + bare(str_lit("unreachable")), // would be String, bare(but never reached) ], TypeAnnotation::Simple(ident("Integer")), span(), diff --git a/crates/beamtalk-core/src/semantic_analysis/validators.rs b/crates/beamtalk-core/src/semantic_analysis/validators.rs index e5a8d6abf..5e3ad82ca 100644 --- a/crates/beamtalk-core/src/semantic_analysis/validators.rs +++ b/crates/beamtalk-core/src/semantic_analysis/validators.rs @@ -419,8 +419,8 @@ pub(crate) fn check_value_slot_assignment( // separate and not subject to value-type immutability rules. for method in &class.methods { let method_selector = method.selector.name(); - for expr in &method.body { - walk_expression(expr, &mut |e| { + for stmt in &method.body { + walk_expression(&stmt.expression, &mut |e| { check_slot_assignment_at( e, class_name, @@ -442,8 +442,8 @@ pub(crate) fn check_value_slot_assignment( let class_name = standalone.class_name.name.as_str(); let is_value = hierarchy.is_value_subclass(class_name); let method_selector = standalone.method.selector.name(); - for expr in &standalone.method.body { - walk_expression(expr, &mut |e| { + for stmt in &standalone.method.body { + walk_expression(&stmt.expression, &mut |e| { check_slot_assignment_at( e, class_name, @@ -531,7 +531,7 @@ fn child_expressions(expr: &Expression) -> Vec<&Expression> { children.extend(arguments.iter()); children } - Expression::Block(block) => block.body.iter().collect(), + Expression::Block(block) => block.body.iter().map(|s| &s.expression).collect(), Expression::Assignment { target, value, .. } => vec![target.as_ref(), value.as_ref()], Expression::Return { value, .. } => vec![value.as_ref()], Expression::Cascade { @@ -668,8 +668,8 @@ pub(crate) fn check_self_capture_in_actor_block( continue; } for method in class.methods.iter().chain(class.class_methods.iter()) { - for expr in &method.body { - walk_expression(expr, &mut |e| { + for stmt in &method.body { + walk_expression(&stmt.expression, &mut |e| { check_self_capture_at(e, diagnostics); }); } @@ -681,8 +681,8 @@ pub(crate) fn check_self_capture_in_actor_block( if !hierarchy.is_actor_subclass(standalone.class_name.name.as_str()) { continue; } - for expr in &standalone.method.body { - walk_expression(expr, &mut |e| { + for stmt in &standalone.method.body { + walk_expression(&stmt.expression, &mut |e| { check_self_capture_at(e, diagnostics); }); } @@ -723,7 +723,10 @@ fn find_self_message_send(expr: &Expression) -> Option { /// Searches a block's body for a message send or cascade directly to `self`. fn find_self_reference_in_block(block: &Block) -> Option { - block.body.iter().find_map(find_self_message_send) + block + .body + .iter() + .find_map(|s| find_self_message_send(&s.expression)) } /// Checks a single expression node for the self-capture pattern. @@ -1059,9 +1062,13 @@ fn walk_expr_for_effect_free(expr: &Expression, diagnostics: &mut Vec) { +fn check_seq_for_effect_free( + exprs: &[crate::ast::ExpressionStatement], + diagnostics: &mut Vec, +) { let len = exprs.len(); - for (i, expr) in exprs.iter().enumerate() { + for (i, stmt) in exprs.iter().enumerate() { + let expr = &stmt.expression; let is_last = i == len - 1; if !is_last && is_effect_free(expr) { let label = effect_free_label(expr); diff --git a/crates/beamtalk-core/src/source_analysis/parser/declarations.rs b/crates/beamtalk-core/src/source_analysis/parser/declarations.rs index e4abd7f52..110ff42b0 100644 --- a/crates/beamtalk-core/src/source_analysis/parser/declarations.rs +++ b/crates/beamtalk-core/src/source_analysis/parser/declarations.rs @@ -9,8 +9,8 @@ //! - Method definitions with optional `sealed` modifier use crate::ast::{ - ClassDefinition, CommentAttachment, Expression, Identifier, KeywordPart, MessageSelector, - MethodDefinition, MethodKind, ParameterDefinition, StandaloneMethodDefinition, + ClassDefinition, CommentAttachment, Expression, ExpressionStatement, Identifier, KeywordPart, + MessageSelector, MethodDefinition, MethodKind, ParameterDefinition, StandaloneMethodDefinition, StateDeclaration, TypeAnnotation, }; use crate::source_analysis::{Span, TokenKind}; @@ -634,7 +634,7 @@ impl Parser { let body = self.parse_method_body(); self.in_method_body = false; - let end = body.last().map_or(start, Expression::span); + let end = body.last().map_or(start, |s| s.expression.span()); let span = start.merge(end); let mut method = MethodDefinition::with_options( @@ -772,7 +772,7 @@ impl Parser { /// Parses a method body (expressions until the next method or end of class). /// /// Statements are separated by periods or newlines (BT-360). - pub(super) fn parse_method_body(&mut self) -> Vec { + pub(super) fn parse_method_body(&mut self) -> Vec { let mut body = Vec::new(); // Parse expressions until we hit something that looks like a new method, @@ -790,7 +790,7 @@ impl Parser { let pos_before = self.current; let expr = self.parse_expression(); let is_error = expr.is_error(); - body.push(expr); + body.push(ExpressionStatement::bare(expr)); // If parse_expression didn't consume any tokens (e.g. nesting // depth exceeded), break to avoid an infinite loop. @@ -844,7 +844,7 @@ impl Parser { } else if self.match_token(&TokenKind::Bang) { // Cast terminator — mark the last expression as a cast if it's a MessageSend. // If the expression is not a MessageSend (e.g. `x := foo bar!`), emit an error. - match body.last_mut() { + match body.last_mut().map(|s| &mut s.expression) { Some(Expression::MessageSend { is_cast, .. }) => *is_cast = true, Some(last) => { let span = last.span(); diff --git a/crates/beamtalk-core/src/source_analysis/parser/expressions.rs b/crates/beamtalk-core/src/source_analysis/parser/expressions.rs index 66e29975f..2a3eda747 100644 --- a/crates/beamtalk-core/src/source_analysis/parser/expressions.rs +++ b/crates/beamtalk-core/src/source_analysis/parser/expressions.rs @@ -17,8 +17,8 @@ //! - Field access (`object.field`) use crate::ast::{ - Block, BlockParameter, CascadeMessage, ExpectCategory, Expression, Identifier, KeywordPart, - Literal, MapPair, MatchArm, MessageSelector, Pattern, StringSegment, + Block, BlockParameter, CascadeMessage, ExpectCategory, Expression, ExpressionStatement, + Identifier, KeywordPart, Literal, MapPair, MatchArm, MessageSelector, Pattern, StringSegment, }; use crate::source_analysis::{Token, TokenKind}; use ecow::EcoString; @@ -642,7 +642,7 @@ impl Parser { while !self.check(&TokenKind::RightBracket) && !self.is_at_end() { let pos_before = self.current; let expr = self.parse_expression(); - body.push(expr); + body.push(ExpressionStatement::bare(expr)); // If parse_expression didn't consume any tokens (e.g. nesting // depth exceeded), break to avoid an infinite loop. @@ -672,7 +672,7 @@ impl Parser { } else if self.match_token(&TokenKind::Bang) { // Cast terminator — mark the last expression as a cast if it's a MessageSend. // If the expression is not a MessageSend (e.g. `x := foo bar!`), emit an error. - match body.last_mut() { + match body.last_mut().map(|s| &mut s.expression) { Some(Expression::MessageSend { is_cast, .. }) => *is_cast = true, Some(last) => { let span = last.span(); diff --git a/crates/beamtalk-core/src/source_analysis/parser/mod.rs b/crates/beamtalk-core/src/source_analysis/parser/mod.rs index 3ad2e4ad9..cdea53170 100644 --- a/crates/beamtalk-core/src/source_analysis/parser/mod.rs +++ b/crates/beamtalk-core/src/source_analysis/parser/mod.rs @@ -50,7 +50,7 @@ //! assert_eq!(module.expressions.len(), 1); //! ``` -use crate::ast::{Comment, CommentKind, Expression, Module}; +use crate::ast::{Comment, CommentKind, Expression, ExpressionStatement, Module}; #[cfg(test)] use crate::ast::{Literal, MessageSelector}; use crate::source_analysis::{Span, Token, TokenKind, Trivia, lex_with_eof}; @@ -713,7 +713,7 @@ impl Parser { } else { let expr = self.parse_expression(); let is_error = expr.is_error(); - expressions.push(expr); + expressions.push(ExpressionStatement::bare(expr)); // If we got an error, try to recover if is_error { @@ -724,7 +724,7 @@ impl Parser { // period consumed — nothing else to do } else if self.match_token(&TokenKind::Bang) { // Cast terminator — annotate the last expression as a cast - match expressions.last_mut() { + match expressions.last_mut().map(|s| &mut s.expression) { Some(Expression::MessageSend { is_cast, .. }) => *is_cast = true, Some(last) => { let span = last.span(); @@ -753,7 +753,7 @@ impl Parser { method_definitions, expressions, span, - leading_comments: comments, + file_leading_comments: comments, } } @@ -911,7 +911,7 @@ mod tests { fn parse_integer_literal() { let module = parse_ok("42"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Literal(Literal::Integer(42), _) => {} _ => panic!("Expected integer literal"), } @@ -921,7 +921,7 @@ mod tests { fn parse_float_literal() { let module = parse_ok("2.5"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Literal(Literal::Float(f), _) if (*f - 2.5_f64).abs() < 0.001 => {} _ => panic!("Expected float literal"), } @@ -931,7 +931,7 @@ mod tests { fn parse_string_literal() { let module = parse_ok("\"hello\""); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Literal(Literal::String(s), _) if s == "hello" => {} _ => panic!("Expected string literal"), } @@ -941,7 +941,7 @@ mod tests { fn parse_symbol_literal() { let module = parse_ok("#symbol"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Literal(Literal::Symbol(s), _) if s == "symbol" => {} _ => panic!("Expected symbol literal"), } @@ -951,7 +951,7 @@ mod tests { fn parse_identifier() { let module = parse_ok("myVar"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Identifier(id) if id.name == "myVar" => {} _ => panic!("Expected identifier"), } @@ -961,7 +961,7 @@ mod tests { fn parse_assignment() { let module = parse_ok("x := 42"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Assignment { target, value, .. } => { assert!(matches!(**target, Expression::Identifier(_))); assert!(matches!( @@ -977,7 +977,7 @@ mod tests { fn parse_unary_message() { let module = parse_ok("3 factorial"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Unary(name), @@ -999,7 +999,7 @@ mod tests { fn parse_binary_message() { let module = parse_ok("3 + 4"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -1028,7 +1028,7 @@ mod tests { assert_eq!(module.expressions.len(), 1); // The AST should be: (2 + (3 * 4)) - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -1069,7 +1069,7 @@ mod tests { fn parse_keyword_message() { let module = parse_ok("array at: 1 put: \"x\""); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Keyword(parts), @@ -1091,7 +1091,7 @@ mod tests { let module = parse_ok("acc isEmpty ifTrue: [cell]\n ifFalse: [\"{acc},{cell}\"]"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { selector: MessageSelector::Keyword(parts), arguments, @@ -1110,7 +1110,7 @@ mod tests { fn parse_keyword_message_multiline_inject_into() { let module = parse_ok("collection inject: 0\n into: [:acc :each | acc + each]"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { selector: MessageSelector::Keyword(parts), arguments, @@ -1129,7 +1129,7 @@ mod tests { fn parse_keyword_message_multiline_to_do() { let module = parse_ok("1 to: 10\n do: [:i | i]"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { selector: MessageSelector::Keyword(parts), arguments, @@ -1171,7 +1171,7 @@ mod tests { fn parse_block_no_params() { let module = parse_ok("[42]"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert!(block.parameters.is_empty()); assert_eq!(block.body.len(), 1); @@ -1184,7 +1184,7 @@ mod tests { fn parse_block_with_params() { let module = parse_ok("[:x :y | x + y]"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!(block.parameters.len(), 2); assert_eq!(block.parameters[0].name.as_str(), "x"); @@ -1199,7 +1199,7 @@ mod tests { fn parse_return_statement() { let module = parse_ok("^42"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Return { value, .. } => { assert!(matches!( **value, @@ -1214,7 +1214,7 @@ mod tests { fn parse_parenthesized() { let module = parse_ok("(3 + 4) * 2"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -1233,7 +1233,7 @@ mod tests { fn parse_field_access() { let module = parse_ok("self.value"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::FieldAccess { receiver, field, .. } => { @@ -1294,7 +1294,7 @@ mod tests { fn parse_cascade() { let module = parse_ok("Transcript show: \"Hello\"; cr; show: \"World\""); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Cascade { receiver, messages, .. } => { @@ -1319,7 +1319,7 @@ mod tests { fn parse_cascade_simple() { let module = parse_ok("x foo; bar; baz"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Cascade { receiver, messages, .. } => { @@ -1344,7 +1344,7 @@ mod tests { // Test that unary messages followed by period work correctly let module = parse_ok("obj foo."); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Unary(name), @@ -1373,7 +1373,7 @@ mod tests { // Plain strings without interpolation still parse as Literal::String let module = parse_ok("\"Hello, world!\""); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Literal(Literal::String(s), _) if s == "Hello, world!" => {} _ => panic!("Expected plain string literal"), } @@ -1386,7 +1386,7 @@ mod tests { "Expected no diagnostics, got: {diagnostics:?}" ); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::StringInterpolation { segments, .. } => { assert_eq!(segments.len(), 3); match &segments[0] { @@ -1422,7 +1422,7 @@ mod tests { let (module, diagnostics) = parse(tokens); assert!(diagnostics.is_empty(), "{diagnostics:?}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::StringInterpolation { segments, .. } => { assert_eq!(segments.len(), 4); // "Name: ", firstName, " ", lastName } @@ -1437,7 +1437,7 @@ mod tests { let (module, diagnostics) = parse(tokens); assert!(diagnostics.is_empty(), "{diagnostics:?}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::StringInterpolation { segments, .. } => { assert_eq!(segments.len(), 2); // "Result: ", (x + 1) assert!(matches!( @@ -1456,7 +1456,7 @@ mod tests { let (module, diagnostics) = parse(tokens); assert!(diagnostics.is_empty(), "{diagnostics:?}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::StringInterpolation { segments, .. } => { assert_eq!(segments.len(), 2); // "Value: ", (dict at: key) assert!(matches!( @@ -1475,7 +1475,7 @@ mod tests { let (module, diagnostics) = parse(tokens); assert!(diagnostics.is_empty(), "{diagnostics:?}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::StringInterpolation { segments, .. } => { // Only the interpolation expression, empty start/end omitted assert_eq!(segments.len(), 1); @@ -1507,7 +1507,7 @@ mod tests { // (not the error discarded as before) assert_eq!(module.expressions.len(), 1); // The assignment should contain the error as its value - if let Expression::Assignment { value, .. } = &module.expressions[0] { + if let Expression::Assignment { value, .. } = &module.expressions[0].expression { assert!(value.is_error()); } } @@ -1517,7 +1517,7 @@ mod tests { // Test that field access doesn't consume statement terminator let module = parse_ok("self.value."); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::FieldAccess { .. } => {} _ => panic!("Expected field access"), } @@ -1528,7 +1528,7 @@ mod tests { // Regression test: ensure `. ` (period + space) is parsed as statement // separator, not field access let module = parse_ok("[ 1 + m. y := 1]"); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!(block.body.len(), 2, "Block should have 2 statements"); } @@ -1540,7 +1540,7 @@ mod tests { fn parse_block_newline_separated_statements() { // BT-360: newlines act as implicit statement separators let module = parse_ok("[\n Transcript show: \"a\"\n Transcript show: \"b\"\n 42\n]"); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!( block.body.len(), @@ -1556,7 +1556,7 @@ mod tests { fn parse_block_mixed_period_and_newline_separators() { // BT-360: periods and newlines can be mixed let module = parse_ok("[\n 1 + 2.\n 3 + 4\n 5\n]"); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!( block.body.len(), @@ -1580,7 +1580,7 @@ mod tests { // Should still parse the block with all three statements assert_eq!(module.expressions.len(), 1, "Should parse the block"); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!( block.body.len(), @@ -1589,17 +1589,20 @@ mod tests { ); // First statement should be valid - assert!(!block.body[0].is_error(), "First statement should be valid"); + assert!( + !block.body[0].expression.is_error(), + "First statement should be valid" + ); // Second statement is assignment with error value assert!( - matches!(&block.body[1], Expression::Assignment { value, .. } if value.is_error()), + matches!(&block.body[1].expression, Expression::Assignment { value, .. } if value.is_error()), "Second statement should be assignment with error value" ); // Third statement should be parsed after error assert!( - !block.body[2].is_error(), + !block.body[2].expression.is_error(), "Third statement should be valid (blocks don't break on errors)" ); } @@ -1664,19 +1667,19 @@ mod tests { // First statement should be valid assert!( - !method.body[0].is_error(), + !method.body[0].expression.is_error(), "First statement should be valid" ); // Second statement should be an error assignment assert!( - matches!(&method.body[1], Expression::Assignment { value, .. } if value.is_error()), + matches!(&method.body[1].expression, Expression::Assignment { value, .. } if value.is_error()), "Second statement should be assignment with error value" ); // Third statement should be parsed after recovery assert!( - !method.body[2].is_error(), + !method.body[2].expression.is_error(), "Third statement should be valid after recovery" ); } @@ -1715,7 +1718,7 @@ mod tests { "Second method should have 1 statement" ); assert!( - !class.methods[1].body[0].is_error(), + !class.methods[1].body[0].expression.is_error(), "Second method statement should be valid" ); } @@ -1748,13 +1751,13 @@ mod tests { // First statement should be valid (x := 1) assert!( - !method.body[0].is_error(), + !method.body[0].expression.is_error(), "First statement should be valid" ); // Last statement should be valid (z := 3) — recovered after error assert!( - !method.body[method.body.len() - 1].is_error(), + !method.body[method.body.len() - 1].expression.is_error(), "Last statement should be valid after recovery" ); } @@ -1825,7 +1828,7 @@ mod tests { let module = parse_ok("#{}"); assert_eq!(module.expressions.len(), 1); assert!(matches!( - &module.expressions[0], + &module.expressions[0].expression, Expression::MapLiteral { pairs, .. } if pairs.is_empty() )); } @@ -1834,7 +1837,7 @@ mod tests { fn parse_map_with_atom_keys() { let module = parse_ok("#{#name => \"Alice\", #age => 30}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); // First pair: #name => "Alice" @@ -1861,12 +1864,21 @@ mod tests { fn parse_block_with_field_assignments() { // Regression test: multiple field assignments should parse correctly let module = parse_ok("[:n | self.x := self.x + n. self.x := self.x + n. ^self.x]"); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!(block.body.len(), 3, "Block should have 3 statements"); - assert!(matches!(block.body[0], Expression::Assignment { .. })); - assert!(matches!(block.body[1], Expression::Assignment { .. })); - assert!(matches!(block.body[2], Expression::Return { .. })); + assert!(matches!( + block.body[0].expression, + Expression::Assignment { .. } + )); + assert!(matches!( + block.body[1].expression, + Expression::Assignment { .. } + )); + assert!(matches!( + block.body[2].expression, + Expression::Return { .. } + )); } _ => panic!("Expected block"), } @@ -1876,7 +1888,7 @@ mod tests { fn parse_map_with_string_keys() { let module = parse_ok("#{\"host\" => \"localhost\", \"port\" => 8080}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); assert!( @@ -1900,7 +1912,7 @@ mod tests { ^self.value ]", ); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Block(block) => { assert_eq!(block.body.len(), 3, "Block should have 3 statements"); } @@ -1912,7 +1924,7 @@ mod tests { fn parse_map_with_integer_keys() { let module = parse_ok("#{1 => \"first\", 2 => \"second\"}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); assert!(matches!( @@ -1931,7 +1943,7 @@ mod tests { fn parse_map_with_trailing_comma() { let module = parse_ok("#{#a => 1, #b => 2,}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); } @@ -1943,7 +1955,7 @@ mod tests { fn parse_nested_maps() { let module = parse_ok("#{#outer => #{#inner => \"value\"}}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 1); // Outer key is #outer @@ -1975,7 +1987,7 @@ mod tests { // BT-664: Map values should support binary expressions let module = parse_ok("#{#x => 1 + 2}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 1); assert!( @@ -2011,7 +2023,7 @@ mod tests { // BT-664: Multiple map values with binary expressions let module = parse_ok("#{#x => 1 + 2, #y => 3 * 4}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); assert!(matches!( @@ -2038,7 +2050,7 @@ mod tests { // BT-664: Map values with unary messages on binary results let module = parse_ok("#{#x => self x + other x}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 1); // Value should be a binary message send (+) @@ -2058,7 +2070,7 @@ mod tests { fn parse_map_assignment() { let module = parse_ok("person := #{#name => \"Alice\"}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Assignment { target, value, .. } => { assert!( matches!(target.as_ref(), Expression::Identifier(id) if id.name == "person") @@ -2079,7 +2091,7 @@ mod tests { assert_eq!(module.expressions.len(), 2, "Expected 2 expressions"); // First: empty := #{} - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::Assignment { target, value, .. } => { assert!( matches!(target.as_ref(), Expression::Identifier(id) if id.name == "empty") @@ -2092,7 +2104,7 @@ mod tests { } // Second: person := #{#name => "Alice", #age => 30} - match &module.expressions[1] { + match &module.expressions[1].expression { Expression::Assignment { target, value, .. } => { assert!( matches!(target.as_ref(), Expression::Identifier(id) if id.name == "person") @@ -2110,7 +2122,7 @@ mod tests { // BT-591: Bare identifiers before `=>` in map literals become implicit symbols let module = parse_ok("#{name => \"Alice\", age => 30}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); // Bare `name` becomes Symbol("name") @@ -2138,7 +2150,7 @@ mod tests { // BT-591: Mixed bare identifier and explicit symbol keys let module = parse_ok("#{x => 1, #y => 2}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 2); // Bare `x` becomes Symbol("x") @@ -2159,7 +2171,7 @@ mod tests { // BT-591: Uppercase identifiers (class references) used as map keys are NOT converted to symbols let module = parse_ok("#{Counter => 1}"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MapLiteral { pairs, .. } => { assert_eq!(pairs.len(), 1); // Uppercase bare identifier `Counter` remains a ClassReference, not an implicit symbol @@ -2604,7 +2616,7 @@ Actor subclass: Rectangle let module = parse_ok("42"); assert_eq!(module.expressions.len(), 1); assert!(matches!( - &module.expressions[0], + &module.expressions[0].expression, Expression::Literal(Literal::Integer(42), _) )); } @@ -2641,7 +2653,7 @@ Actor subclass: Rectangle selector: MessageSelector::Binary(op), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { // Top level should be `+` assert_eq!(op.as_str(), "+"); @@ -2686,7 +2698,7 @@ Actor subclass: Rectangle selector: MessageSelector::Binary(op), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { // Top level should be `-` with `3` on right assert_eq!(op.as_str(), "-"); @@ -2731,7 +2743,7 @@ Actor subclass: Rectangle selector: MessageSelector::Binary(op), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { assert_eq!(op.as_str(), "<"); @@ -2774,7 +2786,10 @@ Actor subclass: Rectangle let module = parse_ok(expr); assert_eq!(module.expressions.len(), 1, "Failed for: {expr}"); assert!( - matches!(&module.expressions[0], Expression::MessageSend { .. }), + matches!( + &module.expressions[0].expression, + Expression::MessageSend { .. } + ), "Expected MessageSend for: {expr}" ); } @@ -2790,7 +2805,7 @@ Actor subclass: Rectangle selector: MessageSelector::Unary(name), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { assert!(matches!(&**receiver, Expression::Super(_))); assert_eq!(name.as_str(), "increment"); @@ -2810,7 +2825,7 @@ Actor subclass: Rectangle selector: MessageSelector::Keyword(parts), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { assert!(matches!(&**receiver, Expression::Super(_))); assert_eq!(parts.len(), 2); @@ -2842,7 +2857,7 @@ Actor subclass: Rectangle receiver, selector: MessageSelector::Unary(name), .. - } = &method.body[0] + } = &method.body[0].expression { assert!(matches!(&**receiver, Expression::Super(_))); assert_eq!(name.as_str(), "increment"); @@ -2860,7 +2875,7 @@ Actor subclass: Rectangle // Currently parses as FieldAccess with Super receiver // This is technically invalid semantically but parser allows it - if let Expression::FieldAccess { receiver, .. } = &module.expressions[0] { + if let Expression::FieldAccess { receiver, .. } = &module.expressions[0].expression { assert!( matches!(&**receiver, Expression::Super(_)), "Parser allows super.field (codegen will reject it)" @@ -2879,7 +2894,7 @@ Actor subclass: Rectangle if let Expression::Cascade { receiver, messages, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { // The receiver should be a MessageSend with Super if let Expression::MessageSend { @@ -2915,7 +2930,7 @@ Actor subclass: Rectangle selector: MessageSelector::Unary(name), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { // Receiver should be ClassReference, not Identifier if let Expression::ClassReference { @@ -2937,7 +2952,7 @@ Actor subclass: Rectangle fn parse_class_reference_vs_variable() { // Uppercase should parse as ClassReference let module1 = parse_ok("Counter"); - if let Expression::ClassReference { name, .. } = &module1.expressions[0] { + if let Expression::ClassReference { name, .. } = &module1.expressions[0].expression { assert_eq!(name.name.as_str(), "Counter"); } else { panic!("Expected ClassReference for 'Counter'"); @@ -2945,7 +2960,7 @@ Actor subclass: Rectangle // Lowercase should parse as Identifier let module2 = parse_ok("counter"); - if let Expression::Identifier(id) = &module2.expressions[0] { + if let Expression::Identifier(id) = &module2.expressions[0].expression { assert_eq!(id.name.as_str(), "counter"); } else { panic!("Expected Identifier for 'counter'"); @@ -2962,7 +2977,7 @@ Actor subclass: Rectangle selector: MessageSelector::Keyword(parts), arguments, .. - } = &module.expressions[0] + } = &module.expressions[0].expression { // Receiver should be ClassReference if let Expression::ClassReference { @@ -2985,7 +3000,7 @@ Actor subclass: Rectangle fn parse_mixed_case_identifier() { // camelCase should parse as Identifier (starts with lowercase) let module = parse_ok("myVariable"); - if let Expression::Identifier(id) = &module.expressions[0] { + if let Expression::Identifier(id) = &module.expressions[0].expression { assert_eq!(id.name.as_str(), "myVariable"); } else { panic!("Expected Identifier for 'myVariable'"); @@ -2993,7 +3008,7 @@ Actor subclass: Rectangle // PascalCase should parse as ClassReference (starts with uppercase) let module = parse_ok("MyClass"); - if let Expression::ClassReference { name, .. } = &module.expressions[0] { + if let Expression::ClassReference { name, .. } = &module.expressions[0].expression { assert_eq!(name.name.as_str(), "MyClass"); } else { panic!("Expected ClassReference for 'MyClass'"); @@ -3013,7 +3028,7 @@ Actor subclass: Rectangle assert_eq!(method.body.len(), 1); if let Expression::Primitive { name, is_quoted, .. - } = &method.body[0] + } = &method.body[0].expression { assert_eq!(name.as_str(), "+"); assert!(is_quoted); @@ -3031,7 +3046,7 @@ Actor subclass: Rectangle assert_eq!(method.body.len(), 1); if let Expression::Primitive { name, is_quoted, .. - } = &method.body[0] + } = &method.body[0].expression { assert_eq!(name.as_str(), "basicNew"); assert!(!is_quoted); @@ -3049,7 +3064,7 @@ Actor subclass: Rectangle let method = &module.classes[0].methods[0]; assert_eq!(method.body.len(), 1); assert!(matches!( - &method.body[0], + &method.body[0].expression, Expression::Primitive { is_quoted: true, .. @@ -3064,7 +3079,10 @@ Actor subclass: Rectangle let module = parse_ok(source); let method = &module.classes[0].methods[0]; assert_eq!(method.body.len(), 2); - assert!(matches!(&method.body[0], Expression::Primitive { .. })); + assert!(matches!( + &method.body[0].expression, + Expression::Primitive { .. } + )); } #[test] @@ -3075,7 +3093,7 @@ Actor subclass: Rectangle assert_eq!(method.body.len(), 1); if let Expression::Primitive { name, is_quoted, .. - } = &method.body[0] + } = &method.body[0].expression { assert_eq!(name.as_str(), "basicNew"); assert!(!is_quoted); @@ -3125,10 +3143,10 @@ Actor subclass: Rectangle let method = &module.classes[0].methods[0]; assert_eq!(method.body.len(), 1); // The body is a block containing the primitive - if let Expression::Block(block) = &method.body[0] { + if let Expression::Block(block) = &method.body[0].expression { assert_eq!(block.body.len(), 1); assert!( - matches!(&block.body[0], Expression::Primitive { .. }), + matches!(&block.body[0].expression, Expression::Primitive { .. }), "Expected Primitive inside block, got: {:?}", block.body[0] ); @@ -3147,7 +3165,7 @@ Actor subclass: Rectangle let module = parse_ok(source); let method = &module.classes[0].methods[0]; assert_eq!(method.body.len(), 1); - match &method.body[0] { + match &method.body[0].expression { Expression::Primitive { name, is_quoted, .. } => { @@ -3165,7 +3183,7 @@ Actor subclass: Rectangle let module = parse_ok(source); let method = &module.classes[0].methods[0]; assert_eq!(method.body.len(), 1); - match &method.body[0] { + match &method.body[0].expression { Expression::Primitive { name, is_quoted, .. } => { @@ -3241,7 +3259,7 @@ Actor subclass: Rectangle fn parse_empty_list() { let module = parse_ok("#()"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert!(elements.is_empty()); assert!(tail.is_none()); @@ -3254,7 +3272,7 @@ Actor subclass: Rectangle fn parse_single_element_list() { let module = parse_ok("#(42)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 1); assert!(tail.is_none()); @@ -3267,7 +3285,7 @@ Actor subclass: Rectangle fn parse_multi_element_list() { let module = parse_ok("#(1, 2, 3)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 3); assert!(tail.is_none()); @@ -3280,7 +3298,7 @@ Actor subclass: Rectangle fn parse_list_trailing_comma() { let module = parse_ok("#(1, 2, 3,)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 3); assert!(tail.is_none()); @@ -3293,7 +3311,7 @@ Actor subclass: Rectangle fn parse_list_cons_syntax() { let module = parse_ok("#(0 | rest)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 1); assert!(tail.is_some()); @@ -3306,7 +3324,7 @@ Actor subclass: Rectangle fn parse_nested_list() { let module = parse_ok("#(#(1, 2), #(3, 4))"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 2); assert!(tail.is_none()); @@ -3322,7 +3340,7 @@ Actor subclass: Rectangle fn parse_list_with_mixed_types() { let module = parse_ok("#(1, \"hello\", #ok)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 3); assert!(tail.is_none()); @@ -3336,7 +3354,7 @@ Actor subclass: Rectangle // List literal as receiver of a message let module = parse_ok("#(1, 2, 3) size"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector, .. } => { @@ -3352,7 +3370,7 @@ Actor subclass: Rectangle // Multiple elements before cons: #(1, 2 | rest) → [1, 2 | rest] let module = parse_ok("#(1, 2 | rest)"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::ListLiteral { elements, tail, .. } => { assert_eq!(elements.len(), 2); assert!(tail.is_some()); @@ -3875,7 +3893,7 @@ Actor subclass: Counter let module = parse_ok("42 match: [_ -> 99]"); assert_eq!(module.expressions.len(), 1); assert!( - matches!(&module.expressions[0], Expression::Match { arms, .. } if arms.len() == 1) + matches!(&module.expressions[0].expression, Expression::Match { arms, .. } if arms.len() == 1) ); } @@ -3884,7 +3902,7 @@ Actor subclass: Counter let module = parse_ok("x match: [1 -> \"one\"; 2 -> \"two\"; _ -> \"other\"]"); assert_eq!(module.expressions.len(), 1); assert!( - matches!(&module.expressions[0], Expression::Match { arms, .. } if arms.len() == 3) + matches!(&module.expressions[0].expression, Expression::Match { arms, .. } if arms.len() == 3) ); } @@ -3893,7 +3911,7 @@ Actor subclass: Counter let module = parse_ok("r match: [{#ok, v} -> v; {#error, _} -> nil]"); assert_eq!(module.expressions.len(), 1); assert!( - matches!(&module.expressions[0], Expression::Match { arms, .. } if arms.len() == 2) + matches!(&module.expressions[0].expression, Expression::Match { arms, .. } if arms.len() == 2) ); } @@ -3901,7 +3919,7 @@ Actor subclass: Counter fn parse_match_with_guard() { let module = parse_ok("n match: [x when: [x > 0] -> x; _ -> 0]"); assert_eq!(module.expressions.len(), 1); - if let Expression::Match { arms, .. } = &module.expressions[0] { + if let Expression::Match { arms, .. } = &module.expressions[0].expression { assert_eq!(arms.len(), 2); assert!(arms[0].guard.is_some()); assert!(arms[1].guard.is_none()); @@ -3913,7 +3931,7 @@ Actor subclass: Counter #[test] fn codegen_simple_match() { let module = parse_ok("42 match: [_ -> 99]"); - let expr = &module.expressions[0]; + let expr = &module.expressions[0].expression; let result = crate::codegen::core_erlang::generate_test_expression(expr, "test_match"); assert!(result.is_ok(), "Codegen failed: {:?}", result.err()); let code = result.unwrap(); @@ -3924,7 +3942,7 @@ Actor subclass: Counter #[test] fn codegen_match_with_arms() { let module = parse_ok("1 match: [1 -> \"one\"; 2 -> \"two\"; _ -> \"other\"]"); - let expr = &module.expressions[0]; + let expr = &module.expressions[0].expression; let result = crate::codegen::core_erlang::generate_test_expression(expr, "test_match"); assert!(result.is_ok(), "Codegen failed: {:?}", result.err()); let code = result.unwrap(); @@ -3935,7 +3953,7 @@ Actor subclass: Counter #[test] fn codegen_empty_match_errors() { let module = parse_ok("42 match: []"); - let expr = &module.expressions[0]; + let expr = &module.expressions[0].expression; let result = crate::codegen::core_erlang::generate_test_expression(expr, "test_match"); assert!(result.is_err(), "Empty match should fail codegen"); } @@ -3963,7 +3981,7 @@ Actor subclass: Counter // BT-414: `**` is a binary operator let module = parse_ok("2 ** 10"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -3990,7 +4008,7 @@ Actor subclass: Counter // BT-414: `3 * 2 ** 4` should be `3 * (2 ** 4)` let module = parse_ok("3 * 2 ** 4"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -4029,7 +4047,7 @@ Actor subclass: Counter // BT-414: `2 ** 3 ** 2` should be `2 ** (3 ** 2)` (right-associative) let module = parse_ok("2 ** 3 ** 2"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { receiver, selector: MessageSelector::Binary(op), @@ -4316,7 +4334,7 @@ Actor subclass: Counter // `foo bar!` should parse as a MessageSend with is_cast = true let module = parse_ok("foo bar!"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { is_cast, selector: MessageSelector::Unary(name), @@ -4337,7 +4355,7 @@ Actor subclass: Counter // `foo bar.` should parse as a MessageSend with is_cast = false let module = parse_ok("foo bar."); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { is_cast, .. } => { assert!( !is_cast, @@ -4353,7 +4371,7 @@ Actor subclass: Counter // `obj doSomething: 42!` should mark the keyword send as cast let module = parse_ok("obj doSomething: 42!"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { is_cast, selector: MessageSelector::Keyword(_), @@ -4387,11 +4405,11 @@ Actor subclass: Counter // `foo bar! baz qux.` — two statements: first cast, second call let module = parse_ok("foo bar!\nbaz qux."); assert_eq!(module.expressions.len(), 2); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { is_cast, .. } => assert!(is_cast), other => panic!("Expected cast MessageSend, got: {other:?}"), } - match &module.expressions[1] { + match &module.expressions[1].expression { Expression::MessageSend { is_cast, .. } => assert!(!is_cast), other => panic!("Expected call MessageSend, got: {other:?}"), } @@ -4402,7 +4420,7 @@ Actor subclass: Counter // `3 + 4!` — binary message send with cast let module = parse_ok("3 + 4!"); assert_eq!(module.expressions.len(), 1); - match &module.expressions[0] { + match &module.expressions[0].expression { Expression::MessageSend { is_cast, selector: MessageSelector::Binary(op), @@ -4420,9 +4438,9 @@ Actor subclass: Counter // `[foo bar!]` — cast inside a block body let module = parse_ok("[foo bar!]"); assert_eq!(module.expressions.len(), 1); - if let Expression::Block(block) = &module.expressions[0] { + if let Expression::Block(block) = &module.expressions[0].expression { assert_eq!(block.body.len(), 1); - match &block.body[0] { + match &block.body[0].expression { Expression::MessageSend { is_cast, .. } => { assert!(is_cast, "Expected cast inside block body"); } diff --git a/crates/beamtalk-core/src/source_analysis/parser/property_tests.rs b/crates/beamtalk-core/src/source_analysis/parser/property_tests.rs index 0d2f001e7..a06475638 100644 --- a/crates/beamtalk-core/src/source_analysis/parser/property_tests.rs +++ b/crates/beamtalk-core/src/source_analysis/parser/property_tests.rs @@ -158,7 +158,7 @@ fn has_error_node(expr: &Expression) -> bool { } Expression::Return { value, .. } => has_error_node(value), Expression::Parenthesized { expression, .. } => has_error_node(expression), - Expression::Block(block) => block.body.iter().any(has_error_node), + Expression::Block(block) => block.body.iter().any(|s| has_error_node(&s.expression)), Expression::Cascade { receiver, messages, .. } => { @@ -199,15 +199,18 @@ fn has_error_node(expr: &Expression) -> bool { /// Checks if a module's AST contains any `Expression::Error` nodes. fn module_has_error_nodes(module: &Module) -> bool { - module.expressions.iter().any(has_error_node) + module + .expressions + .iter() + .any(|s| has_error_node(&s.expression)) || module.classes.iter().any(|cls| { cls.methods .iter() - .any(|m| m.body.iter().any(has_error_node)) + .any(|m| m.body.iter().any(|s| has_error_node(&s.expression))) || cls .class_methods .iter() - .any(|m| m.body.iter().any(has_error_node)) + .any(|m| m.body.iter().any(|s| has_error_node(&s.expression))) || cls .state .iter() @@ -220,7 +223,7 @@ fn module_has_error_nodes(module: &Module) -> bool { || module .method_definitions .iter() - .any(|m| m.method.body.iter().any(has_error_node)) + .any(|m| m.method.body.iter().any(|s| has_error_node(&s.expression))) } /// Internal type names that should never appear in user-facing diagnostics. diff --git a/test-package-compiler/tests/snapshots/compiler_tests__abstract_class_spawn_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__abstract_class_spawn_parser.snap index 266a8b1e8..999c0c65f 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__abstract_class_spawn_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__abstract_class_spawn_parser.snap @@ -34,24 +34,30 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 186, - end: 190, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 186, + end: 190, + }, }, + ), + selector: Unary( + "subclassResponsibility", + ), + arguments: [], + is_cast: false, + span: Span { + start: 186, + end: 213, }, - ), - selector: Unary( - "subclassResponsibility", - ), - arguments: [], - is_cast: false, - span: Span { - start: 186, - end: 213, }, }, ], @@ -84,36 +90,42 @@ Module { ], method_definitions: [], expressions: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Shape", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Shape", + span: Span { + start: 215, + end: 220, + }, + }, span: Span { start: 215, end: 220, }, }, + selector: Unary( + "spawn", + ), + arguments: [], + is_cast: false, span: Span { start: 215, - end: 220, + end: 226, }, }, - selector: Unary( - "spawn", - ), - arguments: [], - is_cast: false, - span: Span { - start: 215, - end: 226, - }, }, ], span: Span { start: 145, end: 226, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_parser.snap index 19c6717ca..a98cd79c8 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,172 +7,196 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "value", - span: Span { - start: 173, - end: 178, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "value", + span: Span { + start: 173, + end: 178, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 182, + end: 183, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 182, + span: Span { + start: 173, end: 183, }, - ), - span: Span { - start: 173, - end: 183, }, }, - Assignment { - target: Identifier( - Identifier { - name: "increment", - span: Span { - start: 185, - end: 194, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "increment", + span: Span { + start: 185, + end: 194, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 200, + end: 204, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 205, + end: 210, + }, + }, span: Span { start: 200, - end: 204, + end: 210, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 205, - end: 210, - }, - }, - span: Span { - start: 200, - end: 210, - }, - }, - value: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 214, + end: 218, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 219, + end: 224, + }, + }, span: Span { start: 214, - end: 218, + end: 224, }, }, - ), - field: Identifier { - name: "value", + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 227, + end: 228, + }, + ), + ], + is_cast: false, span: Span { - start: 219, - end: 224, + start: 214, + end: 228, }, }, span: Span { - start: 214, - end: 224, + start: 200, + end: 228, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 227, - end: 228, - }, - ), - ], - is_cast: false, - span: Span { - start: 214, - end: 228, - }, - }, - span: Span { - start: 200, - end: 228, }, + ], + span: Span { + start: 198, + end: 230, }, - ], - span: Span { - start: 198, - end: 230, }, + ), + span: Span { + start: 185, + end: 230, }, - ), - span: Span { - start: 185, - end: 230, }, }, - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 233, - end: 240, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 233, + end: 240, + }, }, - }, - ), - value: MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Counter", + ), + value: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Counter", + span: Span { + start: 244, + end: 251, + }, + }, span: Span { start: 244, end: 251, }, }, + selector: Unary( + "spawn", + ), + arguments: [], + is_cast: false, span: Span { start: 244, - end: 251, + end: 257, }, }, - selector: Unary( - "spawn", - ), - arguments: [], - is_cast: false, span: Span { - start: 244, + start: 233, end: 257, }, }, - span: Span { - start: 233, - end: 257, - }, }, ], span: Span { start: 173, end: 257, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_with_args_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_with_args_parser.snap index 69ac93d50..c8378f494 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_with_args_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__actor_spawn_with_args_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,172 +7,196 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "value", - span: Span { - start: 368, - end: 373, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "value", + span: Span { + start: 368, + end: 373, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 377, + end: 378, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 377, + span: Span { + start: 368, end: 378, }, - ), - span: Span { - start: 368, - end: 378, }, }, - Assignment { - target: Identifier( - Identifier { - name: "increment", - span: Span { - start: 380, - end: 389, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "increment", + span: Span { + start: 380, + end: 389, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 395, + end: 399, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 400, + end: 405, + }, + }, span: Span { start: 395, - end: 399, + end: 405, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 400, - end: 405, - }, - }, - span: Span { - start: 395, - end: 405, - }, - }, - value: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 409, + end: 413, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 414, + end: 419, + }, + }, span: Span { start: 409, - end: 413, + end: 419, }, }, - ), - field: Identifier { - name: "value", + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 422, + end: 423, + }, + ), + ], + is_cast: false, span: Span { - start: 414, - end: 419, + start: 409, + end: 423, }, }, span: Span { - start: 409, - end: 419, + start: 395, + end: 423, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 422, - end: 423, - }, - ), - ], - is_cast: false, - span: Span { - start: 409, - end: 423, - }, - }, - span: Span { - start: 395, - end: 423, }, + ], + span: Span { + start: 393, + end: 425, }, - ], - span: Span { - start: 393, - end: 425, }, + ), + span: Span { + start: 380, + end: 425, }, - ), - span: Span { - start: 380, - end: 425, }, }, - Assignment { - target: Identifier( - Identifier { - name: "counter1", - span: Span { - start: 469, - end: 477, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter1", + span: Span { + start: 469, + end: 477, + }, }, - }, - ), - value: MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Counter", + ), + value: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Counter", + span: Span { + start: 481, + end: 488, + }, + }, span: Span { start: 481, end: 488, }, }, + selector: Unary( + "spawn", + ), + arguments: [], + is_cast: false, span: Span { start: 481, - end: 488, + end: 494, }, }, - selector: Unary( - "spawn", - ), - arguments: [], - is_cast: false, span: Span { - start: 481, + start: 469, end: 494, }, }, - span: Span { - start: 469, - end: 494, - }, }, ], span: Span { start: 368, end: 494, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__actor_state_mutation_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__actor_state_mutation_parser.snap index 3859e7916..0c5aa7ba5 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__actor_state_mutation_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__actor_state_mutation_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,207 +7,243 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "value", - span: Span { - start: 256, - end: 261, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "value", + span: Span { + start: 256, + end: 261, + }, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 265, + value: Literal( + Integer( + 0, + ), + Span { + start: 265, + end: 266, + }, + ), + span: Span { + start: 256, end: 266, }, - ), - span: Span { - start: 256, - end: 266, }, }, - Assignment { - target: Identifier( - Identifier { - name: "increment", - span: Span { - start: 314, - end: 323, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "increment", + span: Span { + start: 314, + end: 323, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 329, + end: 333, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 334, + end: 339, + }, + }, span: Span { start: 329, - end: 333, + end: 339, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 334, - end: 339, - }, - }, - span: Span { - start: 329, - end: 339, - }, - }, - value: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 343, + end: 347, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 348, + end: 353, + }, + }, span: Span { start: 343, - end: 347, + end: 353, }, }, - ), - field: Identifier { - name: "value", + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 356, + end: 357, + }, + ), + ], + is_cast: false, span: Span { - start: 348, - end: 353, + start: 343, + end: 357, }, }, span: Span { - start: 343, - end: 353, + start: 329, + end: 357, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 360, + end: 364, + }, + }, ), - Span { - start: 356, - end: 357, + field: Identifier { + name: "value", + span: Span { + start: 365, + end: 370, + }, }, - ), - ], - is_cast: false, - span: Span { - start: 343, - end: 357, - }, - }, - span: Span { - start: 329, - end: 357, - }, - }, - Return { - value: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", span: Span { start: 360, - end: 364, + end: 370, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 365, + start: 359, end: 370, }, }, - span: Span { - start: 360, - end: 370, - }, - }, - span: Span { - start: 359, - end: 370, }, + ], + span: Span { + start: 327, + end: 372, }, - ], - span: Span { - start: 327, - end: 372, }, + ), + span: Span { + start: 314, + end: 372, }, - ), - span: Span { - start: 314, - end: 372, }, }, - Assignment { - target: Identifier( - Identifier { - name: "getValue", - span: Span { - start: 410, - end: 418, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "getValue", + span: Span { + start: 410, + end: 418, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Return { - value: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 425, + end: 429, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 430, + end: 435, + }, + }, span: Span { start: 425, - end: 429, + end: 435, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 430, + start: 424, end: 435, }, }, - span: Span { - start: 425, - end: 435, - }, - }, - span: Span { - start: 424, - end: 435, }, + ], + span: Span { + start: 422, + end: 437, }, - ], - span: Span { - start: 422, - end: 437, }, + ), + span: Span { + start: 410, + end: 437, }, - ), - span: Span { - start: 410, - end: 437, }, }, ], @@ -216,7 +251,7 @@ Module { start: 256, end: 438, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__async_keyword_message_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__async_keyword_message_parser.snap index 7252ca2ae..a1ef4a743 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__async_keyword_message_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__async_keyword_message_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,90 +7,102 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "update", - span: Span { - start: 186, - end: 192, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "update", + span: Span { + start: 186, + end: 192, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Return { - value: MessageSend { - receiver: Identifier( - Identifier { - name: "object", - span: Span { - start: 199, - end: 205, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "foo:", - span: Span { - start: 206, - end: 210, - }, - }, - KeywordPart { - keyword: "bar:", - span: Span { - start: 213, - end: 217, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: MessageSend { + receiver: Identifier( + Identifier { + name: "object", + span: Span { + start: 199, + end: 205, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 1, ), - Span { - start: 211, - end: 212, - }, - ), - Literal( - String( - "hello", + selector: Keyword( + [ + KeywordPart { + keyword: "foo:", + span: Span { + start: 206, + end: 210, + }, + }, + KeywordPart { + keyword: "bar:", + span: Span { + start: 213, + end: 217, + }, + }, + ], ), - Span { - start: 218, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 211, + end: 212, + }, + ), + Literal( + String( + "hello", + ), + Span { + start: 218, + end: 225, + }, + ), + ], + is_cast: false, + span: Span { + start: 199, end: 225, }, - ), - ], - is_cast: false, - span: Span { - start: 199, - end: 225, + }, + span: Span { + start: 198, + end: 225, + }, }, }, - span: Span { - start: 198, - end: 225, - }, + ], + span: Span { + start: 196, + end: 227, }, - ], - span: Span { - start: 196, - end: 227, }, + ), + span: Span { + start: 186, + end: 227, }, - ), - span: Span { - start: 186, - end: 227, }, }, ], @@ -99,7 +110,7 @@ Module { start: 186, end: 227, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__async_unary_message_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__async_unary_message_parser.snap index 5cada77af..7b5529476 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__async_unary_message_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__async_unary_message_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,56 +7,68 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "run", - span: Span { - start: 160, - end: 163, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "run", + span: Span { + start: 160, + end: 163, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Return { - value: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 170, + end: 177, + }, + }, + ), + selector: Unary( + "increment", + ), + arguments: [], + is_cast: false, span: Span { start: 170, - end: 177, + end: 187, }, }, - ), - selector: Unary( - "increment", - ), - arguments: [], - is_cast: false, - span: Span { - start: 170, - end: 187, + span: Span { + start: 169, + end: 187, + }, }, }, - span: Span { - start: 169, - end: 187, - }, + ], + span: Span { + start: 167, + end: 189, }, - ], - span: Span { - start: 167, - end: 189, }, + ), + span: Span { + start: 160, + end: 189, }, - ), - span: Span { - start: 160, - end: 189, }, }, ], @@ -65,7 +76,7 @@ Module { start: 160, end: 189, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__async_with_await_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__async_with_await_parser.snap index 1d666f5aa..97f9de308 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__async_with_await_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__async_with_await_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,56 +7,68 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "waitFor", - span: Span { - start: 134, - end: 141, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "waitFor", + span: Span { + start: 134, + end: 141, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Return { - value: MessageSend { - receiver: Identifier( - Identifier { - name: "future", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: MessageSend { + receiver: Identifier( + Identifier { + name: "future", + span: Span { + start: 148, + end: 154, + }, + }, + ), + selector: Unary( + "await", + ), + arguments: [], + is_cast: false, span: Span { start: 148, - end: 154, + end: 160, }, }, - ), - selector: Unary( - "await", - ), - arguments: [], - is_cast: false, - span: Span { - start: 148, - end: 160, + span: Span { + start: 147, + end: 160, + }, }, }, - span: Span { - start: 147, - end: 160, - }, + ], + span: Span { + start: 145, + end: 162, }, - ], - span: Span { - start: 145, - end: 162, }, + ), + span: Span { + start: 134, + end: 162, }, - ), - span: Span { - start: 134, - end: 162, }, }, ], @@ -65,7 +76,7 @@ Module { start: 134, end: 162, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__binary_operators_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__binary_operators_parser.snap index 2be8590a1..25a90c21d 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__binary_operators_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__binary_operators_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,1170 +7,1314 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "addition", - span: Span { - start: 241, - end: 249, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 253, - end: 254, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "addition", + span: Span { + start: 241, + end: 249, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 4, + 3, ), Span { - start: 257, - end: 258, + start: 253, + end: 254, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 257, + end: 258, + }, + ), + ], + is_cast: false, + span: Span { + start: 253, + end: 258, + }, + }, span: Span { - start: 253, + start: 241, end: 258, }, }, - span: Span { - start: 241, - end: 258, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "subtraction", - span: Span { - start: 259, - end: 270, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 274, - end: 276, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "subtraction", + span: Span { + start: 259, + end: 270, + }, }, ), - selector: Binary( - "-", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 3, + 10, ), Span { - start: 279, - end: 280, + start: 274, + end: 276, }, ), - ], - is_cast: false, + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 279, + end: 280, + }, + ), + ], + is_cast: false, + span: Span { + start: 274, + end: 280, + }, + }, span: Span { - start: 274, + start: 259, end: 280, }, }, - span: Span { - start: 259, - end: 280, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "multiplication", - span: Span { - start: 281, - end: 295, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 299, - end: 300, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "multiplication", + span: Span { + start: 281, + end: 295, + }, }, ), - selector: Binary( - "*", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 6, + 5, ), Span { - start: 303, - end: 304, + start: 299, + end: 300, }, ), - ], - is_cast: false, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 6, + ), + Span { + start: 303, + end: 304, + }, + ), + ], + is_cast: false, + span: Span { + start: 299, + end: 304, + }, + }, span: Span { - start: 299, + start: 281, end: 304, }, }, - span: Span { - start: 281, - end: 304, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "division", - span: Span { - start: 305, - end: 313, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 20, - ), - Span { - start: 317, - end: 319, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "division", + span: Span { + start: 305, + end: 313, + }, }, ), - selector: Binary( - "/", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 4, + 20, ), Span { - start: 322, - end: 323, + start: 317, + end: 319, }, ), - ], - is_cast: false, + selector: Binary( + "/", + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 322, + end: 323, + }, + ), + ], + is_cast: false, + span: Span { + start: 317, + end: 323, + }, + }, span: Span { - start: 317, + start: 305, end: 323, }, }, - span: Span { - start: 305, - end: 323, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "modulo", - span: Span { - start: 324, - end: 330, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 17, - ), - Span { - start: 334, - end: 336, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "modulo", + span: Span { + start: 324, + end: 330, + }, }, ), - selector: Binary( - "%", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 5, + 17, ), Span { - start: 339, - end: 340, + start: 334, + end: 336, }, ), - ], - is_cast: false, + selector: Binary( + "%", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 339, + end: 340, + }, + ), + ], + is_cast: false, + span: Span { + start: 334, + end: 340, + }, + }, span: Span { - start: 334, + start: 324, end: 340, }, }, - span: Span { - start: 324, - end: 340, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "exponentiation", - span: Span { - start: 341, - end: 355, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 2, - ), - Span { - start: 359, - end: 360, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "exponentiation", + span: Span { + start: 341, + end: 355, + }, }, ), - selector: Binary( - "**", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 10, + 2, ), Span { - start: 364, - end: 366, + start: 359, + end: 360, }, ), - ], - is_cast: false, + selector: Binary( + "**", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 364, + end: 366, + }, + ), + ], + is_cast: false, + span: Span { + start: 359, + end: 366, + }, + }, span: Span { - start: 359, + start: 341, end: 366, }, }, - span: Span { - start: 341, - end: 366, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "equalityCheck", - span: Span { - start: 404, - end: 417, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 421, - end: 422, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "equalityCheck", + span: Span { + start: 404, + end: 417, + }, }, ), - selector: Binary( - "==", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( 5, ), Span { - start: 426, - end: 427, + start: 421, + end: 422, }, ), - ], - is_cast: false, + selector: Binary( + "==", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 426, + end: 427, + }, + ), + ], + is_cast: false, + span: Span { + start: 421, + end: 427, + }, + }, span: Span { - start: 421, + start: 404, end: 427, }, }, - span: Span { - start: 404, - end: 427, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "looseNotEqualCheck", - span: Span { - start: 454, - end: 472, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, - ), - Span { - start: 476, - end: 478, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "looseNotEqualCheck", + span: Span { + start: 454, + end: 472, + }, }, ), - selector: Binary( - "/=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 99, + 42, ), Span { - start: 482, - end: 484, + start: 476, + end: 478, }, ), - ], - is_cast: false, + selector: Binary( + "/=", + ), + arguments: [ + Literal( + Integer( + 99, + ), + Span { + start: 482, + end: 484, + }, + ), + ], + is_cast: false, + span: Span { + start: 476, + end: 484, + }, + }, span: Span { - start: 476, + start: 454, end: 484, }, }, - span: Span { - start: 454, - end: 484, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "strictEqualCheck", - span: Span { - start: 511, - end: 527, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 531, - end: 538, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "strictEqualCheck", + span: Span { + start: 511, + end: 527, + }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( "hello", ), Span { - start: 543, - end: 550, + start: 531, + end: 538, }, ), - ], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + String( + "hello", + ), + Span { + start: 543, + end: 550, + }, + ), + ], + is_cast: false, + span: Span { + start: 531, + end: 550, + }, + }, span: Span { - start: 531, + start: 511, end: 550, }, }, - span: Span { - start: 511, - end: 550, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "strictNotEqualCheck", - span: Span { - start: 579, - end: 598, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, - ), - Span { - start: 602, - end: 604, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "strictNotEqualCheck", + span: Span { + start: 579, + end: 598, + }, }, ), - selector: Binary( - "=/=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 99, + 42, ), Span { - start: 609, - end: 611, + start: 602, + end: 604, }, ), - ], - is_cast: false, + selector: Binary( + "=/=", + ), + arguments: [ + Literal( + Integer( + 99, + ), + Span { + start: 609, + end: 611, + }, + ), + ], + is_cast: false, + span: Span { + start: 602, + end: 611, + }, + }, span: Span { - start: 602, + start: 579, end: 611, }, }, - span: Span { - start: 579, - end: 611, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "lessThan", - span: Span { - start: 626, - end: 634, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "lessThan", + span: Span { + start: 626, + end: 634, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 638, - end: 639, - }, - ), - selector: Binary( - "<", ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 10, + 3, ), Span { - start: 642, - end: 644, + start: 638, + end: 639, }, ), - ], - is_cast: false, + selector: Binary( + "<", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 642, + end: 644, + }, + ), + ], + is_cast: false, + span: Span { + start: 638, + end: 644, + }, + }, span: Span { - start: 638, + start: 626, end: 644, }, }, - span: Span { - start: 626, - end: 644, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "greaterThan", - span: Span { - start: 662, - end: 673, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 15, - ), - Span { - start: 677, - end: 679, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "greaterThan", + span: Span { + start: 662, + end: 673, + }, }, ), - selector: Binary( - ">", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 8, + 15, ), Span { - start: 682, - end: 683, + start: 677, + end: 679, }, ), - ], - is_cast: false, + selector: Binary( + ">", + ), + arguments: [ + Literal( + Integer( + 8, + ), + Span { + start: 682, + end: 683, + }, + ), + ], + is_cast: false, + span: Span { + start: 677, + end: 683, + }, + }, span: Span { - start: 677, + start: 662, end: 683, }, }, - span: Span { - start: 662, - end: 683, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "lessOrEqual", - span: Span { - start: 707, - end: 718, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 722, - end: 723, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "lessOrEqual", + span: Span { + start: 707, + end: 718, + }, }, ), - selector: Binary( - "<=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( 5, ), Span { - start: 727, - end: 728, + start: 722, + end: 723, }, ), - ], - is_cast: false, + selector: Binary( + "<=", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 727, + end: 728, + }, + ), + ], + is_cast: false, + span: Span { + start: 722, + end: 728, + }, + }, span: Span { - start: 722, + start: 707, end: 728, }, }, - span: Span { - start: 707, - end: 728, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "greaterOrEqual", - span: Span { - start: 755, - end: 769, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 773, - end: 775, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "greaterOrEqual", + span: Span { + start: 755, + end: 769, + }, }, ), - selector: Binary( - ">=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( 10, ), Span { - start: 779, - end: 781, + start: 773, + end: 775, }, ), - ], - is_cast: false, + selector: Binary( + ">=", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 779, + end: 781, + }, + ), + ], + is_cast: false, + span: Span { + start: 773, + end: 781, + }, + }, span: Span { - start: 773, + start: 755, end: 781, }, }, - span: Span { - start: 755, - end: 781, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "stringConcat", - span: Span { - start: 819, - end: 831, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "Hello", - ), - Span { - start: 835, - end: 842, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "stringConcat", + span: Span { + start: 819, + end: 831, + }, }, ), - selector: Binary( - "++", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( - " World", + "Hello", ), Span { - start: 846, - end: 854, + start: 835, + end: 842, }, ), - ], - is_cast: false, + selector: Binary( + "++", + ), + arguments: [ + Literal( + String( + " World", + ), + Span { + start: 846, + end: 854, + }, + ), + ], + is_cast: false, + span: Span { + start: 835, + end: 854, + }, + }, span: Span { - start: 835, + start: 819, end: 854, }, }, - span: Span { - start: 819, - end: 854, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "precedence1", - span: Span { - start: 973, - end: 984, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 2, - ), - Span { - start: 988, - end: 989, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "precedence1", + span: Span { + start: 973, + end: 984, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 992, - end: 993, - }, - ), - selector: Binary( - "*", + value: MessageSend { + receiver: Literal( + Integer( + 2, ), - arguments: [ - Literal( + Span { + start: 988, + end: 989, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + MessageSend { + receiver: Literal( Integer( - 4, + 3, ), Span { - start: 996, - end: 997, + start: 992, + end: 993, }, ), - ], - is_cast: false, - span: Span { - start: 992, - end: 997, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 996, + end: 997, + }, + ), + ], + is_cast: false, + span: Span { + start: 992, + end: 997, + }, }, + ], + is_cast: false, + span: Span { + start: 988, + end: 997, }, - ], - is_cast: false, + }, span: Span { - start: 988, + start: 973, end: 997, }, }, - span: Span { - start: 973, - end: 997, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "precedence2", - span: Span { - start: 1029, - end: 1040, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 1044, - end: 1046, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "precedence2", + span: Span { + start: 1029, + end: 1040, + }, }, ), - selector: Binary( - "-", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 1049, - end: 1050, - }, - ), - selector: Binary( - "/", + value: MessageSend { + receiver: Literal( + Integer( + 10, ), - arguments: [ - Literal( + Span { + start: 1044, + end: 1046, + }, + ), + selector: Binary( + "-", + ), + arguments: [ + MessageSend { + receiver: Literal( Integer( - 2, + 5, ), Span { - start: 1053, - end: 1054, + start: 1049, + end: 1050, }, ), - ], - is_cast: false, - span: Span { - start: 1049, - end: 1054, + selector: Binary( + "/", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1053, + end: 1054, + }, + ), + ], + is_cast: false, + span: Span { + start: 1049, + end: 1054, + }, }, + ], + is_cast: false, + span: Span { + start: 1044, + end: 1054, }, - ], - is_cast: false, + }, span: Span { - start: 1044, + start: 1029, end: 1054, }, }, - span: Span { - start: 1029, - end: 1054, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "nested", - span: Span { - start: 1107, - end: 1113, - }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 1118, - end: 1119, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 4, - ), - Span { - start: 1122, - end: 1123, - }, - ), - ], - is_cast: false, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "nested", span: Span { - start: 1118, - end: 1123, + start: 1107, + end: 1113, }, }, - span: Span { - start: 1117, - end: 1124, - }, - }, - selector: Binary( - "*", ), - arguments: [ - Parenthesized { + value: MessageSend { + receiver: Parenthesized { expression: MessageSend { receiver: Literal( Integer( - 10, + 3, ), Span { - start: 1128, - end: 1130, + start: 1118, + end: 1119, }, ), selector: Binary( - "-", + "+", ), arguments: [ Literal( Integer( - 2, + 4, ), Span { - start: 1133, - end: 1134, + start: 1122, + end: 1123, }, ), ], is_cast: false, span: Span { - start: 1128, - end: 1134, + start: 1118, + end: 1123, }, }, span: Span { - start: 1127, - end: 1135, + start: 1117, + end: 1124, + }, + }, + selector: Binary( + "*", + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Literal( + Integer( + 10, + ), + Span { + start: 1128, + end: 1130, + }, + ), + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1133, + end: 1134, + }, + ), + ], + is_cast: false, + span: Span { + start: 1128, + end: 1134, + }, + }, + span: Span { + start: 1127, + end: 1135, + }, }, + ], + is_cast: false, + span: Span { + start: 1117, + end: 1135, }, - ], - is_cast: false, + }, span: Span { - start: 1117, + start: 1107, end: 1135, }, }, - span: Span { - start: 1107, - end: 1135, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "blockWithOp", - span: Span { - start: 1162, - end: 1173, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "blockWithOp", + span: Span { + start: 1162, + end: 1173, + }, }, - }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 1179, - end: 1180, + ), + value: Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 1179, + end: 1180, + }, }, - }, - BlockParameter { - name: "y", - span: Span { - start: 1182, - end: 1183, + BlockParameter { + name: "y", + span: Span { + start: 1182, + end: 1183, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 1186, - end: 1187, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { + expression: MessageSend { receiver: Identifier( Identifier { - name: "y", + name: "x", span: Span { - start: 1190, - end: 1191, + start: 1186, + end: 1187, }, }, ), selector: Binary( - "*", + "+", ), arguments: [ - Literal( - Integer( - 2, + MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 1190, + end: 1191, + }, + }, + ), + selector: Binary( + "*", ), - Span { - start: 1194, + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1194, + end: 1195, + }, + ), + ], + is_cast: false, + span: Span { + start: 1190, end: 1195, }, - ), + }, ], is_cast: false, span: Span { - start: 1190, + start: 1186, end: 1195, }, }, - ], - is_cast: false, - span: Span { - start: 1186, - end: 1195, }, + ], + span: Span { + start: 1177, + end: 1196, }, - ], - span: Span { - start: 1177, - end: 1196, }, + ), + span: Span { + start: 1162, + end: 1196, }, - ), - span: Span { - start: 1162, - end: 1196, }, }, - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 1250, - end: 1251, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 1250, + end: 1251, + }, }, - }, - ), - value: Literal( - Integer( - 10, ), - Span { - start: 1255, + value: Literal( + Integer( + 10, + ), + Span { + start: 1255, + end: 1257, + }, + ), + span: Span { + start: 1250, end: 1257, }, - ), - span: Span { - start: 1250, - end: 1257, }, }, - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 1258, - end: 1259, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "y", + span: Span { + start: 1258, + end: 1259, + }, }, - }, - ), - value: Literal( - Integer( - 3, ), - Span { - start: 1263, + value: Literal( + Integer( + 3, + ), + Span { + start: 1263, + end: 1264, + }, + ), + span: Span { + start: 1258, end: 1264, }, - ), - span: Span { - start: 1258, - end: 1264, }, }, - Assignment { - target: Identifier( - Identifier { - name: "condition", - span: Span { - start: 1265, - end: 1274, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "condition", + span: Span { + start: 1265, + end: 1274, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 1279, - end: 1280, - }, - }, - ), - selector: Binary( - ">", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 1283, - end: 1284, + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 1279, + end: 1280, + }, }, ), - ], - is_cast: false, + selector: Binary( + ">", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 1283, + end: 1284, + }, + ), + ], + is_cast: false, + span: Span { + start: 1279, + end: 1284, + }, + }, span: Span { - start: 1279, - end: 1284, + start: 1278, + end: 1285, }, }, - span: Span { - start: 1278, - end: 1285, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "and:", - span: Span { - start: 1286, - end: 1290, + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 1286, + end: 1290, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "y", - span: Span { - start: 1292, - end: 1293, - }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 10, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 1292, + end: 1293, + }, + }, + ), + selector: Binary( + "<", ), - Span { - start: 1296, + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 1296, + end: 1298, + }, + ), + ], + is_cast: false, + span: Span { + start: 1292, end: 1298, }, - ), - ], - is_cast: false, - span: Span { - start: 1292, - end: 1298, + }, }, + ], + span: Span { + start: 1291, + end: 1299, }, - ], - span: Span { - start: 1291, - end: 1299, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1278, + end: 1299, + }, + }, span: Span { - start: 1278, + start: 1265, end: 1299, }, }, - span: Span { - start: 1265, - end: 1299, - }, }, ], span: Span { start: 241, end: 1299, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__blocks_no_args_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__blocks_no_args_parser.snap index 31a4e5f5c..ae6fc2163 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__blocks_no_args_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__blocks_no_args_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,435 +7,537 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "noArgs", - span: Span { - start: 171, - end: 177, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "noArgs", + span: Span { + start: 171, + end: 177, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 182, - end: 184, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 182, + end: 184, + }, + ), }, - ), - ], - span: Span { - start: 181, - end: 185, + ], + span: Span { + start: 181, + end: 185, + }, }, + ), + span: Span { + start: 171, + end: 185, }, - ), - span: Span { - start: 171, - end: 185, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result1", - span: Span { - start: 186, - end: 193, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "noArgs", + name: "result1", span: Span { - start: 197, - end: 203, + start: 186, + end: 193, }, }, ), - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "noArgs", + span: Span { + start: 197, + end: 203, + }, + }, + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 197, + end: 209, + }, + }, span: Span { - start: 197, + start: 186, end: 209, }, }, - span: Span { - start: 186, - end: 209, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "outer", - span: Span { - start: 259, - end: 264, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "outer", + span: Span { + start: 259, + end: 264, + }, + }, + ), + value: Literal( + Integer( + 10, + ), + Span { + start: 268, + end: 270, }, - }, - ), - value: Literal( - Integer( - 10, ), - Span { - start: 268, + span: Span { + start: 259, end: 270, }, - ), - span: Span { - start: 259, - end: 270, }, }, - Assignment { - target: Identifier( - Identifier { - name: "captureBlock", - span: Span { - start: 271, - end: 283, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "captureBlock", + span: Span { + start: 271, + end: 283, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "outer", - span: Span { - start: 288, - end: 293, - }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 5, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "outer", + span: Span { + start: 288, + end: 293, + }, + }, ), - Span { - start: 296, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 296, + end: 297, + }, + ), + ], + is_cast: false, + span: Span { + start: 288, end: 297, }, - ), - ], - is_cast: false, - span: Span { - start: 288, - end: 297, + }, }, + ], + span: Span { + start: 287, + end: 298, }, - ], - span: Span { - start: 287, - end: 298, }, + ), + span: Span { + start: 271, + end: 298, }, - ), - span: Span { - start: 271, - end: 298, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 299, - end: 306, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "captureBlock", + name: "result2", span: Span { - start: 310, - end: 322, + start: 299, + end: 306, }, }, ), - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, - span: Span { - start: 310, - end: 328, - }, - }, - span: Span { - start: 299, - end: 328, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "condition", - span: Span { - start: 383, - end: 392, - }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 397, - end: 404, - }, - }, - ), - selector: Binary( - ">", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 407, - end: 408, - }, - ), - ], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "captureBlock", span: Span { - start: 397, - end: 408, + start: 310, + end: 322, }, }, - ], + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { - start: 396, - end: 409, + start: 310, + end: 328, }, }, - ), - span: Span { - start: 383, - end: 409, + span: Span { + start: 299, + end: 328, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "condition", - span: Span { - start: 410, - end: 419, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "condition", span: Span { - start: 420, - end: 430, + start: 383, + end: 392, }, }, - ], - ), - arguments: [ - Block( + ), + value: Block( Block { parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 432, - end: 439, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "counter", span: Span { - start: 443, - end: 450, + start: 397, + end: 404, }, }, ), selector: Binary( - "-", + ">", ), arguments: [ Literal( Integer( - 1, + 0, ), Span { - start: 453, - end: 454, + start: 407, + end: 408, }, ), ], is_cast: false, span: Span { - start: 443, - end: 454, + start: 397, + end: 408, }, }, - span: Span { - start: 432, - end: 454, - }, }, ], span: Span { - start: 431, - end: 455, + start: 396, + end: 409, }, }, ), - ], - is_cast: false, - span: Span { - start: 410, - end: 455, + span: Span { + start: 383, + end: 409, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "block1", - span: Span { - start: 489, - end: 495, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "condition", + span: Span { + start: 410, + end: 419, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 1, - ), - Span { - start: 500, - end: 501, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 420, + end: 430, }, - ), + }, ], - span: Span { - start: 499, - end: 502, - }, + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 432, + end: 439, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 443, + end: 450, + }, + }, + ), + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 453, + end: 454, + }, + ), + ], + is_cast: false, + span: Span { + start: 443, + end: 454, + }, + }, + span: Span { + start: 432, + end: 454, + }, + }, + }, + ], + span: Span { + start: 431, + end: 455, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 410, + end: 455, }, - ), - span: Span { - start: 489, - end: 502, }, }, - Assignment { - target: Identifier( - Identifier { - name: "block2", - span: Span { - start: 503, - end: 509, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "block1", + span: Span { + start: 489, + end: 495, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 2, - ), - Span { - start: 514, - end: 515, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 1, + ), + Span { + start: 500, + end: 501, + }, + ), }, - ), - ], - span: Span { - start: 513, - end: 516, + ], + span: Span { + start: 499, + end: 502, + }, }, + ), + span: Span { + start: 489, + end: 502, }, - ), - span: Span { - start: 503, - end: 516, }, }, - Assignment { - target: Identifier( - Identifier { - name: "block3", - span: Span { - start: 517, - end: 523, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "block2", + span: Span { + start: 503, + end: 509, + }, + }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 2, + ), + Span { + start: 514, + end: 515, + }, + ), + }, + ], + span: Span { + start: 513, + end: 516, + }, }, + ), + span: Span { + start: 503, + end: 516, }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 3, - ), - Span { - start: 528, - end: 529, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "block3", + span: Span { + start: 517, + end: 523, + }, + }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 3, + ), + Span { + start: 528, + end: 529, + }, + ), }, - ), - ], - span: Span { - start: 527, - end: 530, + ], + span: Span { + start: 527, + end: 530, + }, }, + ), + span: Span { + start: 517, + end: 530, }, - ), - span: Span { - start: 517, - end: 530, }, }, ], @@ -444,7 +545,7 @@ Module { start: 171, end: 530, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__boundary_deeply_nested_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__boundary_deeply_nested_parser.snap index 743e1cb0e..48fb28db8 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__boundary_deeply_nested_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__boundary_deeply_nested_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,18 +7,22 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "result1", - span: Span { - start: 243, - end: 250, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result1", + span: Span { + start: 243, + end: 250, + }, }, - }, - ), - value: Parenthesized { - expression: Parenthesized { + ), + value: Parenthesized { expression: Parenthesized { expression: Parenthesized { expression: Parenthesized { @@ -28,768 +31,954 @@ Module { expression: Parenthesized { expression: Parenthesized { expression: Parenthesized { - expression: MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 264, - end: 265, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + expression: Parenthesized { + expression: MessageSend { + receiver: Literal( Integer( - 2, + 1, ), Span { - start: 268, - end: 269, + start: 264, + end: 265, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 268, + end: 269, + }, + ), + ], + is_cast: false, + span: Span { + start: 264, + end: 269, + }, + }, span: Span { - start: 264, - end: 269, + start: 263, + end: 270, }, }, span: Span { - start: 263, - end: 270, + start: 262, + end: 271, }, }, span: Span { - start: 262, - end: 271, + start: 261, + end: 272, }, }, span: Span { - start: 261, - end: 272, + start: 260, + end: 273, }, }, span: Span { - start: 260, - end: 273, + start: 259, + end: 274, }, }, span: Span { - start: 259, - end: 274, + start: 258, + end: 275, }, }, span: Span { - start: 258, - end: 275, + start: 257, + end: 276, }, }, span: Span { - start: 257, - end: 276, + start: 256, + end: 277, }, }, span: Span { - start: 256, - end: 277, + start: 255, + end: 278, }, }, span: Span { - start: 255, - end: 278, + start: 254, + end: 279, }, }, span: Span { - start: 254, + start: 243, end: 279, }, }, - span: Span { - start: 243, - end: 279, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 323, - end: 330, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result2", + span: Span { + start: 323, + end: 330, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { + ), + value: MessageSend { receiver: MessageSend { receiver: MessageSend { receiver: MessageSend { receiver: MessageSend { receiver: MessageSend { receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "object", - span: Span { - start: 334, - end: 340, + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "object", + span: Span { + start: 334, + end: 340, + }, }, + ), + selector: Unary( + "method1", + ), + arguments: [], + is_cast: false, + span: Span { + start: 334, + end: 348, }, - ), + }, selector: Unary( - "method1", + "method2", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 348, + end: 356, }, }, selector: Unary( - "method2", + "method3", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 356, + end: 364, }, }, selector: Unary( - "method3", + "method4", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 364, + end: 372, }, }, selector: Unary( - "method4", + "method5", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 372, + end: 380, }, }, selector: Unary( - "method5", + "method6", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 380, + end: 388, }, }, selector: Unary( - "method6", + "method7", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 388, + end: 396, }, }, selector: Unary( - "method7", + "method8", ), arguments: [], is_cast: false, span: Span { start: 334, - end: 396, + end: 404, }, }, - selector: Unary( - "method8", - ), - arguments: [], - is_cast: false, span: Span { - start: 334, + start: 323, end: 404, }, }, - span: Span { - start: 323, - end: 404, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result3", - span: Span { - start: 451, - end: 458, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "object", + name: "result3", span: Span { - start: 462, - end: 468, + start: 451, + end: 458, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "object", span: Span { - start: 469, - end: 472, + start: 462, + end: 468, }, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "dict", - span: Span { - start: 474, - end: 478, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 469, + end: 472, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "dict", span: Span { - start: 479, - end: 482, + start: 474, + end: 478, }, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "array", - span: Span { - start: 484, - end: 489, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 479, + end: 482, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "array", span: Span { - start: 490, - end: 493, + start: 484, + end: 489, }, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "list", - span: Span { - start: 495, - end: 499, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 490, + end: 493, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "list", span: Span { - start: 500, - end: 503, + start: 495, + end: 499, }, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "map", - span: Span { - start: 505, - end: 508, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 500, + end: 503, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "map", span: Span { - start: 509, - end: 512, + start: 505, + end: 508, }, }, - ], - ), - arguments: [ - Literal( - String( - "key", - ), - Span { - start: 513, - end: 518, - }, ), - ], - is_cast: false, - span: Span { - start: 505, - end: 518, - }, - }, - span: Span { - start: 504, - end: 519, - }, - }, - ], - is_cast: false, - span: Span { - start: 495, - end: 519, - }, - }, - span: Span { - start: 494, - end: 520, - }, - }, - ], - is_cast: false, - span: Span { - start: 484, - end: 520, - }, - }, - span: Span { - start: 483, - end: 521, - }, - }, - ], - is_cast: false, - span: Span { - start: 474, - end: 521, - }, - }, - span: Span { - start: 473, - end: 522, - }, - }, - ], - is_cast: false, - span: Span { - start: 462, - end: 522, - }, - }, - span: Span { - start: 451, - end: 522, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result4", - span: Span { - start: 559, - end: 566, - }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 576, - end: 578, - }, - ), - ], + selector: Keyword( + [ + KeywordPart { + keyword: "at:", span: Span { - start: 575, - end: 579, + start: 509, + end: 512, }, }, + ], + ), + arguments: [ + Literal( + String( + "key", + ), + Span { + start: 513, + end: 518, + }, ), ], + is_cast: false, span: Span { - start: 574, - end: 580, + start: 505, + end: 518, }, }, - ), + span: Span { + start: 504, + end: 519, + }, + }, ], + is_cast: false, span: Span { - start: 573, - end: 581, + start: 495, + end: 519, }, }, - ), + span: Span { + start: 494, + end: 520, + }, + }, ], + is_cast: false, span: Span { - start: 572, - end: 582, + start: 484, + end: 520, }, }, - ), + span: Span { + start: 483, + end: 521, + }, + }, ], + is_cast: false, span: Span { - start: 571, - end: 583, + start: 474, + end: 521, }, }, - ), + span: Span { + start: 473, + end: 522, + }, + }, ], + is_cast: false, span: Span { - start: 570, - end: 584, + start: 462, + end: 522, }, }, - ), - span: Span { - start: 559, - end: 584, + span: Span { + start: 451, + end: 522, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result5", - span: Span { - start: 643, - end: 650, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result4", + span: Span { + start: 559, + end: 566, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 657, - end: 658, - }, - }, - ], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( Block { - parameters: [ - BlockParameter { - name: "y", - span: Span { - start: 664, - end: 665, - }, - }, - ], + parameters: [], body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "z", - span: Span { - start: 671, - end: 672, - }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 675, - end: 676, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "y", + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 576, + end: 578, + }, + ), + }, + ], span: Span { - start: 679, - end: 680, + start: 575, + end: 579, }, }, ), - selector: Binary( - "*", - ), - arguments: [ - Identifier( - Identifier { - name: "z", - span: Span { - start: 683, - end: 684, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 679, - end: 684, - }, }, ], - is_cast: false, span: Span { - start: 675, - end: 684, + start: 574, + end: 580, }, }, - ], - span: Span { - start: 669, - end: 685, - }, + ), }, - ), - ], - span: Span { - start: 668, - end: 686, + ], + span: Span { + start: 573, + end: 581, + }, }, - }, - ), + ), + }, ], span: Span { - start: 662, - end: 687, + start: 572, + end: 582, }, }, ), - ], - span: Span { - start: 661, - end: 688, }, + ], + span: Span { + start: 571, + end: 583, }, - ), - ], - span: Span { - start: 655, - end: 689, - }, - }, - ), - Assignment { - target: Identifier( - Identifier { - name: "result6", - span: Span { - start: 786, - end: 793, }, + ), + }, + ], + span: Span { + start: 570, + end: 584, + }, + }, + ), + span: Span { + start: 559, + end: 584, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result5", + span: Span { + start: 643, + end: 650, + }, + }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: Parenthesized { - expression: Cascade { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "object", + expression: Block( + Block { + parameters: [ + BlockParameter { + name: "x", span: Span { - start: 798, - end: 804, + start: 657, + end: 658, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 805, - end: 808, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - KeywordPart { - keyword: "put:", - span: Span { - start: 827, - end: 831, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [ + BlockParameter { + name: "y", + span: Span { + start: 664, + end: 665, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [ + BlockParameter { + name: "z", + span: Span { + start: 671, + end: 672, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 675, + end: 676, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 679, + end: 680, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Identifier( + Identifier { + name: "z", + span: Span { + start: 683, + end: 684, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 679, + end: 684, + }, + }, + ], + is_cast: false, + span: Span { + start: 675, + end: 684, + }, + }, + }, + ], + span: Span { + start: 669, + end: 685, + }, + }, + ), + }, + ], + span: Span { + start: 668, + end: 686, + }, + }, + ), + }, + ], + span: Span { + start: 662, + end: 687, + }, + }, + ), + }, + ], + span: Span { + start: 661, + end: 688, + }, }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "a", + ), + }, + ], + span: Span { + start: 655, + end: 689, + }, + }, + ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result6", + span: Span { + start: 786, + end: 793, + }, + }, + ), + value: Parenthesized { + expression: Cascade { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "object", + span: Span { + start: 798, + end: 804, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", span: Span { - start: 810, - end: 811, + start: 805, + end: 808, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 812, - end: 815, - }, + KeywordPart { + keyword: "put:", + span: Span { + start: 827, + end: 831, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "b", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "a", + span: Span { + start: 810, + end: 811, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", span: Span { - start: 817, - end: 818, + start: 812, + end: 815, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 819, - end: 822, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "b", + span: Span { + start: 817, + end: 818, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 1, ), - Span { - start: 823, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 819, + end: 822, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 823, + end: 824, + }, + ), + ], + is_cast: false, + span: Span { + start: 817, end: 824, }, - ), - ], - is_cast: false, - span: Span { - start: 817, - end: 824, + }, + span: Span { + start: 816, + end: 825, + }, }, - }, + ], + is_cast: false, span: Span { - start: 816, + start: 810, end: 825, }, }, - ], - is_cast: false, - span: Span { - start: 810, - end: 825, + span: Span { + start: 809, + end: 826, + }, }, - }, - span: Span { - start: 809, - end: 826, - }, - }, - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "x", + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 833, + end: 834, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "get:", + span: Span { + start: 835, + end: 839, + }, + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 841, + end: 842, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "get:", + span: Span { + start: 843, + end: 847, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 848, + end: 849, + }, + ), + ], + is_cast: false, + span: Span { + start: 841, + end: 849, + }, + }, + span: Span { + start: 840, + end: 850, + }, + }, + ], + is_cast: false, span: Span { start: 833, - end: 834, + end: 850, }, }, - ), + span: Span { + start: 832, + end: 851, + }, + }, + ], + is_cast: false, + span: Span { + start: 798, + end: 851, + }, + }, + messages: [ + CascadeMessage { selector: Keyword( [ KeywordPart { - keyword: "get:", + keyword: "at:", + span: Span { + start: 853, + end: 856, + }, + }, + KeywordPart { + keyword: "put:", span: Span { - start: 835, - end: 839, + start: 875, + end: 879, }, }, ], @@ -799,276 +988,194 @@ Module { expression: MessageSend { receiver: Identifier( Identifier { - name: "y", + name: "c", span: Span { - start: 841, - end: 842, + start: 858, + end: 859, }, }, ), selector: Keyword( [ KeywordPart { - keyword: "get:", + keyword: "at:", span: Span { - start: 843, - end: 847, + start: 860, + end: 863, }, }, ], ), arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 848, - end: 849, + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "d", + span: Span { + start: 865, + end: 866, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 867, + end: 870, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 871, + end: 872, + }, + ), + ], + is_cast: false, + span: Span { + start: 865, + end: 872, + }, }, - ), + span: Span { + start: 864, + end: 873, + }, + }, ], is_cast: false, span: Span { - start: 841, - end: 849, + start: 858, + end: 873, }, }, span: Span { - start: 840, - end: 850, + start: 857, + end: 874, }, }, - ], - is_cast: false, - span: Span { - start: 833, - end: 850, - }, - }, - span: Span { - start: 832, - end: 851, - }, - }, - ], - is_cast: false, - span: Span { - start: 798, - end: 851, - }, - }, - messages: [ - CascadeMessage { - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 853, - end: 856, - }, - }, - KeywordPart { - keyword: "put:", - span: Span { - start: 875, - end: 879, - }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "c", - span: Span { - start: 858, - end: 859, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 860, - end: 863, + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "z", + span: Span { + start: 881, + end: 882, + }, }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "d", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "get:", span: Span { - start: 865, - end: 866, + start: 883, + end: 887, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 867, - end: 870, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "w", + span: Span { + start: 889, + end: 890, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 3, ), - Span { - start: 871, - end: 872, - }, - ), - ], - is_cast: false, - span: Span { - start: 865, - end: 872, - }, - }, - span: Span { - start: 864, - end: 873, - }, - }, - ], - is_cast: false, - span: Span { - start: 858, - end: 873, - }, - }, - span: Span { - start: 857, - end: 874, - }, - }, - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "z", - span: Span { - start: 881, - end: 882, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "get:", - span: Span { - start: 883, - end: 887, - }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "w", + selector: Keyword( + [ + KeywordPart { + keyword: "get:", + span: Span { + start: 891, + end: 895, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 896, + end: 897, + }, + ), + ], + is_cast: false, span: Span { start: 889, - end: 890, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "get:", - span: Span { - start: 891, - end: 895, - }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 4, - ), - Span { - start: 896, end: 897, }, - ), - ], - is_cast: false, - span: Span { - start: 889, - end: 897, + }, + span: Span { + start: 888, + end: 898, + }, }, - }, + ], + is_cast: false, span: Span { - start: 888, + start: 881, end: 898, }, }, - ], - is_cast: false, - span: Span { - start: 881, - end: 898, + span: Span { + start: 880, + end: 899, + }, }, - }, + ], span: Span { - start: 880, + start: 853, end: 899, }, }, ], span: Span { - start: 853, + start: 798, end: 899, }, }, - ], + span: Span { + start: 797, + end: 900, + }, + }, span: Span { - start: 798, - end: 899, + start: 786, + end: 900, }, }, - span: Span { - start: 797, - end: 900, - }, - }, - span: Span { - start: 786, - end: 900, }, + ], + span: Span { + start: 654, + end: 655, }, - ], - span: Span { - start: 654, - end: 655, }, + ), + span: Span { + start: 643, + end: 655, }, - ), - span: Span { - start: 643, - end: 655, }, }, ], @@ -1076,7 +1183,7 @@ Module { start: 243, end: 900, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__boundary_long_identifiers_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__boundary_long_identifiers_parser.snap index 522f00d41..3f05380d8 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__boundary_long_identifiers_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__boundary_long_identifiers_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,197 +7,239 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "thisIsAVeryLongIdentifierNameThatTestsTheParserAbilityToHandleExtremelyLongVariableNamesWithoutIssues", - span: Span { - start: 218, - end: 319, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "thisIsAVeryLongIdentifierNameThatTestsTheParserAbilityToHandleExtremelyLongVariableNamesWithoutIssues", + span: Span { + start: 218, + end: 319, + }, }, - }, - ), - value: Literal( - Integer( - 42, ), - Span { - start: 323, + value: Literal( + Integer( + 42, + ), + Span { + start: 323, + end: 325, + }, + ), + span: Span { + start: 218, end: 325, }, - ), - span: Span { - start: 218, - end: 325, }, }, - Assignment { - target: Identifier( - Identifier { - name: "longString", - span: Span { - start: 373, - end: 383, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "longString", + span: Span { + start: 373, + end: 383, + }, }, - }, - ), - value: Literal( - String( - "This is an extremely long string literal that contains a lot of text to test the lexer and parser ability to handle very long string tokens without issues or buffer overflows and to ensure proper memory allocation", ), - Span { - start: 387, + value: Literal( + String( + "This is an extremely long string literal that contains a lot of text to test the lexer and parser ability to handle very long string tokens without issues or buffer overflows and to ensure proper memory allocation", + ), + Span { + start: 387, + end: 602, + }, + ), + span: Span { + start: 373, end: 602, }, - ), - span: Span { - start: 373, - end: 602, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 662, - end: 668, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 662, + end: 668, + }, }, - }, - ), - value: Identifier( - Identifier { - name: "veryLongObjectWithManyMethods", - span: Span { - start: 672, - end: 701, + ), + value: Identifier( + Identifier { + name: "veryLongObjectWithManyMethods", + span: Span { + start: 672, + end: 701, + }, }, + ), + span: Span { + start: 662, + end: 701, }, - ), - span: Span { - start: 662, - end: 701, }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found thisIsAVeryLongKeywordPart:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found thisIsAVeryLongKeywordPart:", + span: Span { + start: 707, + end: 734, + }, + }, + selector: Unary( + "value1", + ), + arguments: [], + is_cast: false, span: Span { start: 707, - end: 734, + end: 741, }, }, - selector: Unary( - "value1", - ), - arguments: [], - is_cast: false, - span: Span { - start: 707, - end: 741, - }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found andAnotherVeryLongKeywordPart:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found andAnotherVeryLongKeywordPart:", + span: Span { + start: 747, + end: 777, + }, + }, + selector: Unary( + "value2", + ), + arguments: [], + is_cast: false, span: Span { start: 747, - end: 777, + end: 784, }, }, - selector: Unary( - "value2", - ), - arguments: [], - is_cast: false, - span: Span { - start: 747, - end: 784, - }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found andYetAnotherExtremelyLongKeywordPart:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found andYetAnotherExtremelyLongKeywordPart:", + span: Span { + start: 789, + end: 827, + }, + }, + selector: Unary( + "value3", + ), + arguments: [], + is_cast: false, span: Span { start: 789, - end: 827, + end: 834, }, }, - selector: Unary( - "value3", - ), - arguments: [], - is_cast: false, - span: Span { - start: 789, - end: 834, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "anotherVeryLongIdentifierForTestingPurposes", - span: Span { - start: 873, - end: 916, - }, - }, - ), - value: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "yetAnotherLongIdentifierName", - span: Span { - start: 926, - end: 954, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "anotherVeryLongIdentifierForTestingPurposes", + span: Span { + start: 873, + end: 916, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 955, - end: 958, - }, - }, - ], - ), - arguments: [ - Identifier( + }, + ), + value: Parenthesized { + expression: MessageSend { + receiver: Identifier( Identifier { - name: "evenMoreLongIdentifierNames", + name: "yetAnotherLongIdentifierName", span: Span { - start: 968, - end: 995, + start: 926, + end: 954, }, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 955, + end: 958, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "evenMoreLongIdentifierNames", + span: Span { + start: 968, + end: 995, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 926, + end: 995, + }, + }, span: Span { - start: 926, - end: 995, + start: 920, + end: 997, }, }, span: Span { - start: 920, + start: 873, end: 997, }, }, - span: Span { - start: 873, - end: 997, - }, }, ], span: Span { start: 218, end: 997, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__boundary_mixed_errors_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__boundary_mixed_errors_parser.snap index 72ba859af..f04c27183 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__boundary_mixed_errors_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__boundary_mixed_errors_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,190 +7,214 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 224, - end: 225, - }, - }, - ), - value: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found :=", - span: Span { - start: 229, - end: 231, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 224, + end: 225, + }, }, - }, - selector: Binary( - "+", ), - arguments: [ - Error { + value: MessageSend { + receiver: Error { message: "Unexpected token: expected expression, found :=", span: Span { - start: 234, - end: 236, + start: 229, + end: 231, }, }, - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Error { + message: "Unexpected token: expected expression, found :=", + span: Span { + start: 234, + end: 236, + }, + }, + ], + is_cast: false, + span: Span { + start: 229, + end: 236, + }, + }, span: Span { - start: 229, + start: 224, end: 236, }, }, - span: Span { - start: 224, - end: 236, - }, }, - Literal( - Integer( - 42, - ), - Span { - start: 237, - end: 239, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Assignment { - target: Identifier( - Identifier { - name: "str", - span: Span { - start: 287, - end: 290, - }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 237, + end: 239, }, ), - value: MessageSend { - receiver: MessageSend { + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "str", + span: Span { + start: 287, + end: 290, + }, + }, + ), + value: MessageSend { receiver: MessageSend { - receiver: Literal( - String( - "unterminated\ny := 10\n\n// Invalid assignment with missing operand\nresult := x + + y\n\n// Multiple malformed messages in sequence\nobject at: put: get:\narray add: remove:\n\n// Nested error (malformed message inside valid structure)\nouter := (inner at: missing: broken)\n\n// Mixed errors: unterminated string + invalid syntax + malformed message\nbroken := ", + receiver: MessageSend { + receiver: Literal( + String( + "unterminated\ny := 10\n\n// Invalid assignment with missing operand\nresult := x + + y\n\n// Multiple malformed messages in sequence\nobject at: put: get:\narray add: remove:\n\n// Nested error (malformed message inside valid structure)\nouter := (inner at: missing: broken)\n\n// Mixed errors: unterminated string + invalid syntax + malformed message\nbroken := ", + ), + Span { + start: 294, + end: 645, + }, ), - Span { + selector: Unary( + "unclosed", + ), + arguments: [], + is_cast: false, + span: Span { start: 294, - end: 645, + end: 653, }, + }, + selector: Binary( + "+", ), - selector: Unary( - "unclosed", - ), - arguments: [], + arguments: [ + Error { + message: "Unexpected token: expected expression, found :=", + span: Span { + start: 656, + end: 658, + }, + }, + ], is_cast: false, span: Span { start: 294, - end: 653, + end: 658, }, }, - selector: Binary( - "+", + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 659, + end: 662, + }, + }, + ], ), arguments: [ - Error { - message: "Unexpected token: expected expression, found :=", - span: Span { - start: 656, - end: 658, + Literal( + Integer( + 42, + ), + Span { + start: 663, + end: 665, }, - }, + ), ], is_cast: false, span: Span { start: 294, - end: 658, + end: 665, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 659, - end: 662, - }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 42, - ), - Span { - start: 663, - end: 665, - }, - ), - ], - is_cast: false, span: Span { - start: 294, + start: 287, end: 665, }, }, - span: Span { - start: 287, - end: 665, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "validAfterErrors", - span: Span { - start: 722, - end: 738, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 100, - ), - Span { - start: 742, - end: 745, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "validAfterErrors", + span: Span { + start: 722, + end: 738, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 200, + 100, ), Span { - start: 748, - end: 751, + start: 742, + end: 745, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 200, + ), + Span { + start: 748, + end: 751, + }, + ), + ], + is_cast: false, + span: Span { + start: 742, + end: 751, + }, + }, span: Span { - start: 742, + start: 722, end: 751, }, }, - span: Span { - start: 722, - end: 751, - }, }, ], span: Span { start: 224, end: 751, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__boundary_unicode_identifiers_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__boundary_unicode_identifiers_parser.snap index f16dea75e..eb5c0e399 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__boundary_unicode_identifiers_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__boundary_unicode_identifiers_parser.snap @@ -7,20 +7,32 @@ Module { classes: [], method_definitions: [], expressions: [ - Identifier( - Identifier { - name: "caf", - span: Span { - start: 323, - end: 326, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "caf", + span: Span { + start: 323, + end: 326, + }, }, + ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Error { - message: "Invalid assignment target", - span: Span { - start: 326, - end: 328, + expression: Error { + message: "Invalid assignment target", + span: Span { + start: 326, + end: 328, + }, }, }, ], @@ -28,7 +40,7 @@ Module { start: 323, end: 800, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__cascade_complex_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__cascade_complex_parser.snap index af1d74c0b..36f1e47f0 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__cascade_complex_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__cascade_complex_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,233 +7,305 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 208, - end: 215, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 208, + end: 215, + }, }, - }, - ), - value: MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Counter", + ), + value: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Counter", + span: Span { + start: 219, + end: 226, + }, + }, span: Span { start: 219, end: 226, }, }, + selector: Unary( + "new", + ), + arguments: [], + is_cast: false, span: Span { start: 219, - end: 226, + end: 230, }, }, - selector: Unary( - "new", - ), - arguments: [], - is_cast: false, span: Span { - start: 219, + start: 208, end: 230, }, }, - span: Span { - start: 208, - end: 230, - }, }, - Identifier( - Identifier { - name: "counter", - span: Span { - start: 231, - end: 238, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Cascade { - receiver: Identifier( + expression: Identifier( Identifier { - name: "increment", + name: "counter", span: Span { - start: 244, - end: 253, + start: 231, + end: 238, }, }, ), - messages: [ - CascadeMessage { - selector: Unary( - "increment", - ), - arguments: [], - span: Span { - start: 259, - end: 268, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Cascade { + receiver: Identifier( + Identifier { + name: "increment", + span: Span { + start: 244, + end: 253, + }, + }, + ), + messages: [ + CascadeMessage { + selector: Unary( + "increment", + ), + arguments: [], + span: Span { + start: 259, + end: 268, + }, }, + CascadeMessage { + selector: Unary( + "getValue", + ), + arguments: [], + span: Span { + start: 274, + end: 282, + }, + }, + ], + span: Span { + start: 244, + end: 282, }, - CascadeMessage { - selector: Unary( - "getValue", - ), - arguments: [], + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "object", span: Span { - start: 274, - end: 282, + start: 317, + end: 323, }, }, - ], - span: Span { - start: 244, - end: 282, - }, + ), }, - Identifier( - Identifier { - name: "object", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found at:", span: Span { - start: 317, - end: 323, + start: 328, + end: 331, }, }, - ), - Error { - message: "Unexpected token: expected expression, found at:", - span: Span { - start: 328, - end: 331, - }, }, - Error { - message: "Unexpected token: expected expression, found ;", - span: Span { - start: 350, - end: 351, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Error { - message: "Unexpected token: expected expression, found ;", - span: Span { - start: 378, - end: 379, + expression: Error { + message: "Unexpected token: expected expression, found ;", + span: Span { + start: 350, + end: 351, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ;", - span: Span { - start: 495, - end: 496, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ;", + span: Span { + start: 378, + end: 379, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ;", - span: Span { - start: 507, - end: 508, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ;", + span: Span { + start: 495, + end: 496, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 517, - end: 518, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ;", + span: Span { + start: 507, + end: 508, + }, }, }, - Cascade { - receiver: Error { - message: "Unexpected token: expected expression, found ]", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", span: Span { - start: 574, - end: 575, + start: 517, + end: 518, }, }, - messages: [ - CascadeMessage { - selector: Keyword( - [ - KeywordPart { - keyword: "with:", - span: Span { - start: 581, - end: 586, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Cascade { + receiver: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 574, + end: 575, + }, + }, + messages: [ + CascadeMessage { + selector: Keyword( + [ + KeywordPart { + keyword: "with:", + span: Span { + start: 581, + end: 586, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 589, - end: 590, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 589, + end: 590, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 593, - end: 594, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 593, + end: 594, + }, + }, + ), + selector: Binary( + "*", ), - Span { - start: 597, + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 597, + end: 598, + }, + ), + ], + is_cast: false, + span: Span { + start: 593, end: 598, }, - ), - ], - is_cast: false, - span: Span { - start: 593, - end: 598, + }, }, + ], + span: Span { + start: 587, + end: 599, }, - ], - span: Span { - start: 587, - end: 599, }, - }, - ), - ], - span: Span { - start: 581, - end: 599, + ), + ], + span: Span { + start: 581, + end: 599, + }, }, - }, - CascadeMessage { - selector: Unary( - "execute", - ), - arguments: [], - span: Span { - start: 605, - end: 612, + CascadeMessage { + selector: Unary( + "execute", + ), + arguments: [], + span: Span { + start: 605, + end: 612, + }, }, + ], + span: Span { + start: 574, + end: 612, }, - ], - span: Span { - start: 574, - end: 612, }, }, ], @@ -242,7 +313,7 @@ Module { start: 208, end: 612, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__cascades_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__cascades_parser.snap index 027c3ebe4..26f7d15f3 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__cascades_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__cascades_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,78 +7,90 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "runCascade", - span: Span { - start: 208, - end: 218, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "runCascade", + span: Span { + start: 208, + end: 218, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Cascade { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Cascade { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 224, + end: 231, + }, + }, + ), + selector: Unary( + "increment", + ), + arguments: [], + is_cast: false, span: Span { start: 224, - end: 231, + end: 241, }, }, - ), - selector: Unary( - "increment", - ), - arguments: [], - is_cast: false, - span: Span { - start: 224, - end: 241, - }, - }, - messages: [ - CascadeMessage { - selector: Unary( - "increment", - ), - arguments: [], - span: Span { - start: 243, - end: 252, - }, - }, - CascadeMessage { - selector: Unary( - "getValue", - ), - arguments: [], + messages: [ + CascadeMessage { + selector: Unary( + "increment", + ), + arguments: [], + span: Span { + start: 243, + end: 252, + }, + }, + CascadeMessage { + selector: Unary( + "getValue", + ), + arguments: [], + span: Span { + start: 254, + end: 262, + }, + }, + ], span: Span { - start: 254, + start: 224, end: 262, }, }, - ], - span: Span { - start: 224, - end: 262, }, + ], + span: Span { + start: 222, + end: 264, }, - ], - span: Span { - start: 222, - end: 264, }, + ), + span: Span { + start: 208, + end: 264, }, - ), - span: Span { - start: 208, - end: 264, }, }, ], @@ -87,7 +98,7 @@ Module { start: 208, end: 264, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__character_literals_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__character_literals_parser.snap index 8d41d18ae..4398eecde 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__character_literals_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__character_literals_parser.snap @@ -7,284 +7,338 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "letterA", - span: Span { - start: 180, - end: 187, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "letterA", + span: Span { + start: 180, + end: 187, + }, }, - }, - ), - value: Literal( - Character( - 'A', ), - Span { - start: 191, + value: Literal( + Character( + 'A', + ), + Span { + start: 191, + end: 193, + }, + ), + span: Span { + start: 180, end: 193, }, - ), - span: Span { - start: 180, - end: 193, }, }, - Assignment { - target: Identifier( - Identifier { - name: "letterZ", - span: Span { - start: 194, - end: 201, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "letterZ", + span: Span { + start: 194, + end: 201, + }, }, - }, - ), - value: Literal( - Character( - 'z', ), - Span { - start: 205, - end: 207, - }, - ), - span: Span { - start: 194, - end: 207, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "digit", - span: Span { - start: 208, - end: 213, + value: Literal( + Character( + 'z', + ), + Span { + start: 205, + end: 207, }, - }, - ), - value: Literal( - Character( - '0', ), - Span { - start: 217, - end: 219, + span: Span { + start: 194, + end: 207, }, - ), - span: Span { - start: 208, - end: 219, }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEqual", - span: Span { - start: 257, - end: 264, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "digit", + span: Span { + start: 208, + end: 213, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( + ), + value: Literal( Character( - 'A', + '0', ), Span { - start: 268, - end: 270, + start: 217, + end: 219, }, ), - selector: Binary( - "=", + span: Span { + start: 208, + end: 219, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEqual", + span: Span { + start: 257, + end: 264, + }, + }, ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Character( 'A', ), Span { - start: 273, - end: 275, + start: 268, + end: 270, }, ), - ], - is_cast: false, + selector: Binary( + "=", + ), + arguments: [ + Literal( + Character( + 'A', + ), + Span { + start: 273, + end: 275, + }, + ), + ], + is_cast: false, + span: Span { + start: 268, + end: 275, + }, + }, span: Span { - start: 268, + start: 257, end: 275, }, }, - span: Span { - start: 257, - end: 275, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isLess", - span: Span { - start: 276, - end: 282, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Character( - 'A', - ), - Span { - start: 286, - end: 288, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isLess", + span: Span { + start: 276, + end: 282, + }, }, ), - selector: Binary( - "<", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Character( - 'Z', + 'A', ), Span { - start: 291, - end: 293, + start: 286, + end: 288, }, ), - ], - is_cast: false, + selector: Binary( + "<", + ), + arguments: [ + Literal( + Character( + 'Z', + ), + Span { + start: 291, + end: 293, + }, + ), + ], + is_cast: false, + span: Span { + start: 286, + end: 293, + }, + }, span: Span { - start: 286, + start: 276, end: 293, }, }, - span: Span { - start: 276, - end: 293, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "asInt", - span: Span { - start: 331, - end: 336, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "asInt", + span: Span { + start: 331, + end: 336, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Character( - 'A', + ), + value: MessageSend { + receiver: Literal( + Character( + 'A', + ), + Span { + start: 340, + end: 342, + }, ), - Span { + selector: Unary( + "asInteger", + ), + arguments: [], + is_cast: false, + span: Span { start: 340, - end: 342, + end: 352, }, - ), - selector: Unary( - "asInteger", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 340, + start: 331, end: 352, }, }, - span: Span { - start: 331, - end: 352, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "asStr", - span: Span { - start: 353, - end: 358, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "asStr", + span: Span { + start: 353, + end: 358, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Character( - 'A', + ), + value: MessageSend { + receiver: Literal( + Character( + 'A', + ), + Span { + start: 362, + end: 364, + }, ), - Span { + selector: Unary( + "asString", + ), + arguments: [], + is_cast: false, + span: Span { start: 362, - end: 364, + end: 373, }, - ), - selector: Unary( - "asString", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 362, + start: 353, end: 373, }, }, - span: Span { - start: 353, - end: 373, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "newline", - span: Span { - start: 407, - end: 414, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "newline", + span: Span { + start: 407, + end: 414, + }, + }, + ), + value: Literal( + Character( + '\n', + ), + Span { + start: 418, + end: 421, }, - }, - ), - value: Literal( - Character( - '\n', ), - Span { - start: 418, + span: Span { + start: 407, end: 421, }, - ), - span: Span { - start: 407, - end: 421, }, }, - Assignment { - target: Identifier( - Identifier { - name: "tab", - span: Span { - start: 422, - end: 425, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "tab", + span: Span { + start: 422, + end: 425, + }, + }, + ), + value: Literal( + Character( + '\t', + ), + Span { + start: 429, + end: 432, }, - }, - ), - value: Literal( - Character( - '\t', ), - Span { - start: 429, + span: Span { + start: 422, end: 432, }, - ), - span: Span { - start: 422, - end: 432, }, }, ], @@ -292,7 +346,7 @@ Module { start: 180, end: 432, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__class_definition_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__class_definition_parser.snap index 159741d84..4568f96bb 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__class_definition_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__class_definition_parser.snap @@ -65,76 +65,82 @@ Module { ), parameters: [], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 163, - end: 167, - }, - }, - ), - field: Identifier { - name: "value", - span: Span { - start: 168, - end: 173, - }, - }, - span: Span { - start: 163, - end: 173, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 177, - end: 181, + start: 163, + end: 167, }, }, ), field: Identifier { name: "value", span: Span { - start: 182, - end: 187, + start: 168, + end: 173, }, }, span: Span { - start: 177, - end: 187, + start: 163, + end: 173, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 177, + end: 181, + }, + }, ), - Span { - start: 190, - end: 191, + field: Identifier { + name: "value", + span: Span { + start: 182, + end: 187, + }, }, + span: Span { + start: 177, + end: 187, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 190, + end: 191, + }, + ), + ], + is_cast: false, + span: Span { + start: 177, + end: 191, + }, + }, span: Span { - start: 177, + start: 163, end: 191, }, }, - span: Span { - start: 163, - end: 191, - }, }, ], return_type: None, @@ -156,33 +162,39 @@ Module { ), parameters: [], body: [ - Return { - value: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 207, + end: 211, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 207, - end: 211, + start: 212, + end: 217, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 212, + start: 207, end: 217, }, }, span: Span { - start: 207, + start: 206, end: 217, }, }, - span: Span { - start: 206, - end: 217, - }, }, ], return_type: None, @@ -218,7 +230,7 @@ Module { start: 104, end: 217, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__class_methods_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__class_methods_parser.snap index 6252ed8f4..9eebaae5e 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__class_methods_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__class_methods_parser.snap @@ -65,76 +65,82 @@ Module { ), parameters: [], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 368, - end: 372, - }, - }, - ), - field: Identifier { - name: "count", - span: Span { - start: 373, - end: 378, - }, - }, - span: Span { - start: 368, - end: 378, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 382, - end: 386, + start: 368, + end: 372, }, }, ), field: Identifier { name: "count", span: Span { - start: 387, - end: 392, + start: 373, + end: 378, }, }, span: Span { - start: 382, - end: 392, + start: 368, + end: 378, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 382, + end: 386, + }, + }, ), - Span { - start: 395, - end: 396, + field: Identifier { + name: "count", + span: Span { + start: 387, + end: 392, + }, }, + span: Span { + start: 382, + end: 392, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 395, + end: 396, + }, + ), + ], + is_cast: false, + span: Span { + start: 382, + end: 396, + }, + }, span: Span { - start: 382, + start: 368, end: 396, }, }, - span: Span { - start: 368, - end: 396, - }, }, ], return_type: None, @@ -156,27 +162,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 412, + end: 416, + }, + }, + ), + field: Identifier { + name: "count", span: Span { - start: 412, - end: 416, + start: 417, + end: 422, }, }, - ), - field: Identifier { - name: "count", span: Span { - start: 417, + start: 412, end: 422, }, }, - span: Span { - start: 412, - end: 422, - }, }, ], return_type: None, @@ -200,95 +212,107 @@ Module { ), parameters: [], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 244, - end: 248, - }, - }, - ), - field: Identifier { - name: "instanceCount", - span: Span { - start: 249, - end: 262, - }, - }, - span: Span { - start: 244, - end: 262, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 266, - end: 270, + start: 244, + end: 248, }, }, ), field: Identifier { name: "instanceCount", span: Span { - start: 271, - end: 284, + start: 249, + end: 262, }, }, span: Span { - start: 266, - end: 284, + start: 244, + end: 262, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 266, + end: 270, + }, + }, ), - Span { - start: 287, - end: 288, + field: Identifier { + name: "instanceCount", + span: Span { + start: 271, + end: 284, + }, }, + span: Span { + start: 266, + end: 284, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 287, + end: 288, + }, + ), + ], + is_cast: false, + span: Span { + start: 266, + end: 288, + }, + }, span: Span { - start: 266, + start: 244, end: 288, }, }, - span: Span { - start: 244, - end: 288, - }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 293, - end: 297, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 293, + end: 297, + }, }, + ), + selector: Unary( + "spawn", + ), + arguments: [], + is_cast: false, + span: Span { + start: 293, + end: 303, }, - ), - selector: Unary( - "spawn", - ), - arguments: [], - is_cast: false, - span: Span { - start: 293, - end: 303, }, }, ], @@ -311,27 +335,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 329, + end: 333, + }, + }, + ), + field: Identifier { + name: "instanceCount", span: Span { - start: 329, - end: 333, + start: 334, + end: 347, }, }, - ), - field: Identifier { - name: "instanceCount", span: Span { - start: 334, + start: 329, end: 347, }, }, - span: Span { - start: 329, - end: 347, - }, }, ], return_type: None, @@ -397,7 +427,7 @@ Module { start: 138, end: 422, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__comment_handling_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__comment_handling_parser.snap index c06836ad7..9c2598dbf 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__comment_handling_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__comment_handling_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,162 +7,210 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 161, - end: 162, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 161, + end: 162, + }, }, - }, - ), - value: Literal( - Integer( - 5, ), - Span { - start: 166, + value: Literal( + Integer( + 5, + ), + Span { + start: 166, + end: 167, + }, + ), + span: Span { + start: 161, end: 167, }, - ), - span: Span { - start: 161, - end: 167, }, }, - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 244, - end: 245, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "y", + span: Span { + start: 244, + end: 245, + }, }, - }, - ), - value: Literal( - Integer( - 10, ), - Span { - start: 249, + value: Literal( + Integer( + 10, + ), + Span { + start: 249, + end: 251, + }, + ), + span: Span { + start: 244, end: 251, }, - ), - span: Span { - start: 244, - end: 251, }, }, - Assignment { - target: Identifier( - Identifier { - name: "a", - span: Span { - start: 284, - end: 285, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "a", + span: Span { + start: 284, + end: 285, + }, + }, + ), + value: Literal( + Integer( + 1, + ), + Span { + start: 289, + end: 290, }, - }, - ), - value: Literal( - Integer( - 1, ), - Span { - start: 289, + span: Span { + start: 284, end: 290, }, - ), - span: Span { - start: 284, - end: 290, }, }, - Assignment { - target: Identifier( - Identifier { - name: "b", - span: Span { - start: 309, - end: 310, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "b", + span: Span { + start: 309, + end: 310, + }, + }, + ), + value: Literal( + Integer( + 2, + ), + Span { + start: 314, + end: 315, }, - }, - ), - value: Literal( - Integer( - 2, ), - Span { - start: 314, + span: Span { + start: 309, end: 315, }, - ), - span: Span { - start: 309, - end: 315, }, }, - Identifier( - Identifier { - name: "object", - span: Span { - start: 344, - end: 350, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "object", + span: Span { + start: 344, + end: 350, + }, }, + ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found message:", + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found message:", + span: Span { + start: 371, + end: 379, + }, + }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { start: 371, - end: 379, + end: 385, }, }, - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, - span: Span { - start: 371, - end: 385, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "block", - span: Span { - start: 422, - end: 427, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "block", + span: Span { + start: 422, + end: 427, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 457, - end: 459, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 457, + end: 459, + }, + ), }, - ), - ], - span: Span { - start: 431, - end: 461, + ], + span: Span { + start: 431, + end: 461, + }, }, + ), + span: Span { + start: 422, + end: 461, }, - ), - span: Span { - start: 422, - end: 461, }, }, ], @@ -171,7 +218,7 @@ Module { start: 161, end: 461, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_errors_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_errors_parser.snap index 31cc336fb..1058d8924 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_errors_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_errors_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,121 +7,187 @@ Module { classes: [], method_definitions: [], expressions: [ - Error { - message: "Invalid assignment target", - span: Span { - start: 258, - end: 265, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Invalid assignment target", + span: Span { + start: 258, + end: 265, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 306, - end: 307, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 306, + end: 307, + }, }, }, - Error { - message: "Invalid assignment target", - span: Span { - start: 411, - end: 417, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Invalid assignment target", + span: Span { + start: 411, + end: 417, + }, }, }, - MessageSend { - receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found .", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 425, + end: 426, + }, + }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { start: 425, - end: 426, + end: 431, }, }, - selector: Unary( - "value", + selector: Binary( + "+", ), - arguments: [], + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 434, + end: 435, + }, + ), + ], is_cast: false, span: Span { start: 425, - end: 431, + end: 435, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 434, - end: 435, - }, - ), - ], - is_cast: false, - span: Span { - start: 425, - end: 435, - }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 435, - end: 436, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 435, + end: 436, + }, }, }, - Return { - value: Identifier( - Identifier { - name: "myBlock", - span: Span { - start: 447, - end: 454, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "myBlock", + span: Span { + start: 447, + end: 454, + }, }, + ), + span: Span { + start: 446, + end: 454, }, - ), - span: Span { - start: 446, - end: 454, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 456, - end: 457, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 456, + end: 457, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 556, - end: 557, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 556, + end: 557, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 592, - end: 593, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 592, + end: 593, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 622, - end: 623, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 622, + end: 623, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 634, - end: 635, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 634, + end: 635, + }, }, }, ], @@ -130,7 +195,7 @@ Module { start: 258, end: 635, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_parser.snap index 44c1fc146..2db0dcc21 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__control_flow_mutations_parser.snap @@ -7,1045 +7,1067 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "count", - span: Span { - start: 376, - end: 381, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "count", + span: Span { + start: 376, + end: 381, + }, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 385, + value: Literal( + Integer( + 0, + ), + Span { + start: 385, + end: 386, + }, + ), + span: Span { + start: 376, end: 386, }, - ), - span: Span { - start: 376, - end: 386, }, }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "count", - span: Span { - start: 389, - end: 394, - }, - }, - ), - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 3, - ), - Span { - start: 397, - end: 398, - }, - ), - ], - is_cast: false, - span: Span { - start: 389, - end: 398, - }, - }, - ], - span: Span { - start: 388, - end: 399, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 400, - end: 410, - }, - }, - ], - ), - arguments: [ - Block( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( Block { parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "count", - span: Span { - start: 412, - end: 417, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "count", span: Span { - start: 421, - end: 426, + start: 389, + end: 394, }, }, ), selector: Binary( - "+", + "<", ), arguments: [ Literal( Integer( - 1, + 3, ), Span { - start: 429, - end: 430, + start: 397, + end: 398, }, ), ], is_cast: false, span: Span { - start: 421, - end: 430, + start: 389, + end: 398, }, }, - span: Span { - start: 412, - end: 430, - }, }, ], span: Span { - start: 411, - end: 431, + start: 388, + end: 399, }, }, ), - ], - is_cast: false, - span: Span { - start: 388, - end: 431, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "count2", - span: Span { - start: 485, - end: 491, - }, - }, - ), - value: Literal( - Integer( - 10, + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 400, + end: 410, + }, + }, + ], ), - Span { - start: 495, - end: 497, - }, - ), - span: Span { - start: 485, - end: 497, - }, - }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "count2", - span: Span { - start: 500, - end: 506, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - selector: Binary( - "=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 509, - end: 510, + expression: Assignment { + target: Identifier( + Identifier { + name: "count", + span: Span { + start: 412, + end: 417, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "count", + span: Span { + start: 421, + end: 426, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 429, + end: 430, + }, + ), + ], + is_cast: false, + span: Span { + start: 421, + end: 430, + }, + }, + span: Span { + start: 412, + end: 430, + }, }, - ), + }, ], - is_cast: false, span: Span { - start: 500, - end: 510, + start: 411, + end: 431, }, }, - ], - span: Span { - start: 499, - end: 511, - }, + ), + ], + is_cast: false, + span: Span { + start: 388, + end: 431, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileFalse:", + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "count2", span: Span { - start: 512, - end: 523, + start: 485, + end: 491, }, }, - ], - ), - arguments: [ - Block( + ), + value: Literal( + Integer( + 10, + ), + Span { + start: 495, + end: 497, + }, + ), + span: Span { + start: 485, + end: 497, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( Block { parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "count2", - span: Span { - start: 525, - end: 531, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "count2", span: Span { - start: 535, - end: 541, + start: 500, + end: 506, }, }, ), selector: Binary( - "-", + "=", ), arguments: [ Literal( Integer( - 1, + 0, ), Span { - start: 544, - end: 545, + start: 509, + end: 510, }, ), ], is_cast: false, span: Span { - start: 535, - end: 545, + start: 500, + end: 510, }, }, - span: Span { - start: 525, - end: 545, - }, }, ], span: Span { - start: 524, - end: 546, + start: 499, + end: 511, }, }, ), - ], - is_cast: false, - span: Span { - start: 499, - end: 546, + selector: Keyword( + [ + KeywordPart { + keyword: "whileFalse:", + span: Span { + start: 512, + end: 523, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "count2", + span: Span { + start: 525, + end: 531, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "count2", + span: Span { + start: 535, + end: 541, + }, + }, + ), + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 544, + end: 545, + }, + ), + ], + is_cast: false, + span: Span { + start: 535, + end: 545, + }, + }, + span: Span { + start: 525, + end: 545, + }, + }, + }, + ], + span: Span { + start: 524, + end: 546, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 499, + end: 546, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 615, - end: 618, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", + span: Span { + start: 615, + end: 618, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 622, + end: 623, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 622, + span: Span { + start: 615, end: 623, }, - ), - span: Span { - start: 615, - end: 623, }, }, - Assignment { - target: Identifier( - Identifier { - name: "product", - span: Span { - start: 625, - end: 632, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "product", + span: Span { + start: 625, + end: 632, + }, + }, + ), + value: Literal( + Integer( + 1, + ), + Span { + start: 636, + end: 637, }, - }, - ), - value: Literal( - Integer( - 1, ), - Span { - start: 636, + span: Span { + start: 625, end: 637, }, - ), - span: Span { - start: 625, - end: 637, }, }, - Assignment { - target: Identifier( - Identifier { - name: "i", - span: Span { - start: 639, - end: 640, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "i", + span: Span { + start: 639, + end: 640, + }, + }, + ), + value: Literal( + Integer( + 1, + ), + Span { + start: 644, + end: 645, }, - }, - ), - value: Literal( - Integer( - 1, ), - Span { - start: 644, + span: Span { + start: 639, end: 645, }, - ), - span: Span { - start: 639, - end: 645, }, }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "i", - span: Span { - start: 648, - end: 649, - }, - }, - ), - selector: Binary( - "<=", - ), - arguments: [ - Literal( - Integer( - 3, - ), - Span { - start: 653, - end: 654, - }, - ), - ], - is_cast: false, - span: Span { - start: 648, - end: 654, - }, - }, - ], - span: Span { - start: 647, - end: 655, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 656, - end: 666, - }, - }, - ], - ), - arguments: [ - Block( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( Block { parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 673, - end: 676, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { - name: "sum", + name: "i", span: Span { - start: 680, - end: 683, + start: 648, + end: 649, }, }, ), selector: Binary( - "+", + "<=", ), arguments: [ - Identifier( - Identifier { - name: "i", - span: Span { - start: 686, - end: 687, - }, + Literal( + Integer( + 3, + ), + Span { + start: 653, + end: 654, }, ), ], is_cast: false, span: Span { - start: 680, - end: 687, + start: 648, + end: 654, }, }, - span: Span { - start: 673, - end: 687, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "product", + ], + span: Span { + start: 647, + end: 655, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 656, + end: 666, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", + span: Span { + start: 673, + end: 676, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "sum", + span: Span { + start: 680, + end: 683, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "i", + span: Span { + start: 686, + end: 687, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 680, + end: 687, + }, + }, span: Span { - start: 693, - end: 700, + start: 673, + end: 687, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "product", + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "product", + span: Span { + start: 693, + end: 700, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "product", + span: Span { + start: 704, + end: 711, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Identifier( + Identifier { + name: "i", + span: Span { + start: 714, + end: 715, + }, + }, + ), + ], + is_cast: false, span: Span { start: 704, - end: 711, + end: 715, }, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Identifier( + span: Span { + start: 693, + end: 715, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { name: "i", span: Span { - start: 714, - end: 715, + start: 721, + end: 722, }, }, ), - ], - is_cast: false, - span: Span { - start: 704, - end: 715, - }, - }, - span: Span { - start: 693, - end: 715, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "i", - span: Span { - start: 721, - end: 722, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "i", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "i", + span: Span { + start: 726, + end: 727, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 730, + end: 731, + }, + ), + ], + is_cast: false, span: Span { start: 726, - end: 727, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 730, end: 731, }, - ), - ], - is_cast: false, - span: Span { - start: 726, - end: 731, + }, + span: Span { + start: 721, + end: 731, + }, }, }, - span: Span { - start: 721, - end: 731, - }, + ], + span: Span { + start: 667, + end: 733, }, - ], + }, + ), + ], + is_cast: false, + span: Span { + start: 647, + end: 733, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", span: Span { - start: 667, - end: 733, + start: 948, + end: 955, }, }, ), - ], - is_cast: false, - span: Span { - start: 647, - end: 733, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 948, - end: 955, + value: Literal( + Integer( + 0, + ), + Span { + start: 959, + end: 960, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 959, + span: Span { + start: 948, end: 960, }, - ), - span: Span { - start: 948, - end: 960, }, }, - MessageSend { - receiver: Literal( - Integer( - 5, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 962, + end: 963, + }, ), - Span { - start: 962, - end: 963, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "timesRepeat:", - span: Span { - start: 964, - end: 976, + selector: Keyword( + [ + KeywordPart { + keyword: "timesRepeat:", + span: Span { + start: 964, + end: 976, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 978, - end: 985, - }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 989, - end: 996, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 978, + end: 985, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 989, + end: 996, + }, + }, ), - Span { - start: 999, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 999, + end: 1000, + }, + ), + ], + is_cast: false, + span: Span { + start: 989, end: 1000, }, - ), - ], - is_cast: false, - span: Span { - start: 989, - end: 1000, - }, - }, - span: Span { - start: 978, - end: 1000, + }, + span: Span { + start: 978, + end: 1000, + }, + }, }, + ], + span: Span { + start: 977, + end: 1001, }, - ], + }, + ), + ], + is_cast: false, + span: Span { + start: 962, + end: 1001, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "total", span: Span { - start: 977, - end: 1001, + start: 1066, + end: 1071, }, }, ), - ], - is_cast: false, - span: Span { - start: 962, - end: 1001, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "total", - span: Span { - start: 1066, - end: 1071, + value: Literal( + Integer( + 0, + ), + Span { + start: 1075, + end: 1076, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 1075, + span: Span { + start: 1066, end: 1076, }, - ), - span: Span { - start: 1066, - end: 1076, }, }, - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 1078, - end: 1079, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", - span: Span { - start: 1080, - end: 1083, - }, - }, - KeywordPart { - keyword: "do:", - span: Span { - start: 1087, - end: 1090, - }, - }, - ], - ), - arguments: [ - Literal( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( Integer( - 10, + 1, ), Span { - start: 1084, - end: 1086, + start: 1078, + end: 1079, }, ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 1093, - end: 1094, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 1080, + end: 1083, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "total", - span: Span { - start: 1097, - end: 1102, - }, + }, + KeywordPart { + keyword: "do:", + span: Span { + start: 1087, + end: 1090, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 1084, + end: 1086, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 1093, + end: 1094, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "total", - span: Span { - start: 1106, - end: 1111, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "n", + name: "total", span: Span { - start: 1114, - end: 1115, + start: 1097, + end: 1102, }, }, ), - ], - is_cast: false, - span: Span { - start: 1106, - end: 1115, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "total", + span: Span { + start: 1106, + end: 1111, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 1114, + end: 1115, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1106, + end: 1115, + }, + }, + span: Span { + start: 1097, + end: 1115, + }, }, }, - span: Span { - start: 1097, - end: 1115, - }, + ], + span: Span { + start: 1091, + end: 1116, }, - ], - span: Span { - start: 1091, - end: 1116, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 1078, - end: 1116, + ), + ], + is_cast: false, + span: Span { + start: 1078, + end: 1116, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "numbers", - span: Span { - start: 1314, - end: 1321, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "numbers", + span: Span { + start: 1314, + end: 1321, + }, }, - }, - ), - value: ArrayLiteral { - elements: [ - Literal( - Integer( - 1, + ), + value: ArrayLiteral { + elements: [ + Literal( + Integer( + 1, + ), + Span { + start: 1327, + end: 1328, + }, ), - Span { - start: 1327, - end: 1328, - }, - ), - Literal( - Integer( - 2, + Literal( + Integer( + 2, + ), + Span { + start: 1330, + end: 1331, + }, ), - Span { - start: 1330, - end: 1331, - }, - ), - Literal( - Integer( - 3, + Literal( + Integer( + 3, + ), + Span { + start: 1333, + end: 1334, + }, ), - Span { - start: 1333, - end: 1334, - }, - ), - Literal( - Integer( - 4, + Literal( + Integer( + 4, + ), + Span { + start: 1336, + end: 1337, + }, ), - Span { - start: 1336, - end: 1337, - }, - ), - Literal( - Integer( - 5, + Literal( + Integer( + 5, + ), + Span { + start: 1339, + end: 1340, + }, ), - Span { - start: 1339, - end: 1340, - }, - ), - ], - span: Span { - start: 1325, - end: 1341, - }, - }, - span: Span { - start: 1314, - end: 1341, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "arraySum", + ], span: Span { - start: 1343, - end: 1351, + start: 1325, + end: 1341, }, }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 1355, - end: 1356, + span: Span { + start: 1314, + end: 1341, }, - ), - span: Span { - start: 1343, - end: 1356, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "numbers", - span: Span { - start: 1358, - end: 1365, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "do:", - span: Span { - start: 1366, - end: 1369, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 1372, - end: 1373, - }, - }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "arraySum", - span: Span { - start: 1376, - end: 1384, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "arraySum", - span: Span { - start: 1388, - end: 1396, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "n", - span: Span { - start: 1399, - end: 1400, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 1388, - end: 1400, - }, - }, - span: Span { - start: 1376, - end: 1400, - }, - }, - ], + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "arraySum", span: Span { - start: 1370, - end: 1401, + start: 1343, + end: 1351, }, }, ), - ], - is_cast: false, - span: Span { - start: 1358, - end: 1401, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "evenCount", - span: Span { - start: 1491, - end: 1500, + value: Literal( + Integer( + 0, + ), + Span { + start: 1355, + end: 1356, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 1504, - end: 1505, + span: Span { + start: 1343, + end: 1356, }, - ), - span: Span { - start: 1491, - end: 1505, }, }, - Assignment { - target: Identifier( - Identifier { - name: "doubled", - span: Span { - start: 1507, - end: 1514, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "numbers", span: Span { - start: 1518, - end: 1525, + start: 1358, + end: 1365, }, }, ), selector: Keyword( [ KeywordPart { - keyword: "collect:", + keyword: "do:", span: Span { - start: 1526, - end: 1534, + start: 1366, + end: 1369, }, }, ], @@ -1057,1980 +1079,2492 @@ Module { BlockParameter { name: "n", span: Span { - start: 1537, - end: 1538, + start: 1372, + end: 1373, }, }, ], body: [ - Assignment { - target: Identifier( - Identifier { - name: "evenCount", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "arraySum", + span: Span { + start: 1376, + end: 1384, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "arraySum", + span: Span { + start: 1388, + end: 1396, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 1399, + end: 1400, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 1545, - end: 1554, + start: 1388, + end: 1400, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "evenCount", - span: Span { - start: 1558, - end: 1567, + span: Span { + start: 1376, + end: 1400, + }, + }, + }, + ], + span: Span { + start: 1370, + end: 1401, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1358, + end: 1401, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "evenCount", + span: Span { + start: 1491, + end: 1500, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 1504, + end: 1505, + }, + ), + span: Span { + start: 1491, + end: 1505, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "doubled", + span: Span { + start: 1507, + end: 1514, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "numbers", + span: Span { + start: 1518, + end: 1525, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "collect:", + span: Span { + start: 1526, + end: 1534, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 1537, + end: 1538, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "evenCount", + span: Span { + start: 1545, + end: 1554, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "n", + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "evenCount", + span: Span { + start: 1558, + end: 1567, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 1571, + end: 1572, + }, + }, + ), + selector: Binary( + "%", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1575, + end: 1576, + }, + ), + ], + is_cast: false, span: Span { start: 1571, - end: 1572, - }, - }, - ), - selector: Binary( - "%", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 1575, end: 1576, }, - ), - ], - is_cast: false, - span: Span { - start: 1571, - end: 1576, - }, - }, - selector: Binary( - "=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 1579, - end: 1580, - }, - ), - ], - is_cast: false, - span: Span { - start: 1571, - end: 1580, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 1581, - end: 1588, - }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 1593, - end: 1601, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ + selector: Binary( + "=", + ), + arguments: [ Literal( Integer( - 1, + 0, ), Span { - start: 1590, - end: 1591, + start: 1579, + end: 1580, }, ), ], + is_cast: false, span: Span { - start: 1589, - end: 1592, + start: 1571, + end: 1580, }, }, - ), - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 1603, - end: 1604, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 1581, + end: 1588, }, - ), + }, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 1593, + end: 1601, + }, + }, ], - span: Span { - start: 1602, - end: 1605, - }, + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 1, + ), + Span { + start: 1590, + end: 1591, + }, + ), + }, + ], + span: Span { + start: 1589, + end: 1592, + }, + }, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 0, + ), + Span { + start: 1603, + end: 1604, + }, + ), + }, + ], + span: Span { + start: 1602, + end: 1605, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1571, + end: 1605, }, - ), - ], - is_cast: false, - span: Span { - start: 1571, - end: 1605, + }, + span: Span { + start: 1570, + end: 1606, + }, }, - }, + ], + is_cast: false, span: Span { - start: 1570, + start: 1558, end: 1606, }, }, - ], - is_cast: false, - span: Span { - start: 1558, - end: 1606, - }, - }, - span: Span { - start: 1545, - end: 1606, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "n", span: Span { - start: 1612, - end: 1613, + start: 1545, + end: 1606, }, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 1612, + end: 1613, + }, + }, ), - Span { - start: 1616, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1616, + end: 1617, + }, + ), + ], + is_cast: false, + span: Span { + start: 1612, end: 1617, }, - ), - ], - is_cast: false, - span: Span { - start: 1612, - end: 1617, + }, }, + ], + span: Span { + start: 1535, + end: 1619, }, - ], - span: Span { - start: 1535, - end: 1619, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1518, + end: 1619, + }, + }, span: Span { - start: 1518, + start: 1507, end: 1619, }, }, - span: Span { - start: 1507, - end: 1619, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "matchCount", - span: Span { - start: 1703, - end: 1713, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "matchCount", + span: Span { + start: 1703, + end: 1713, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 1717, + end: 1718, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 1717, + span: Span { + start: 1703, end: 1718, }, - ), - span: Span { - start: 1703, - end: 1718, }, }, - Assignment { - target: Identifier( - Identifier { - name: "evens", - span: Span { - start: 1720, - end: 1725, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "numbers", + name: "evens", span: Span { - start: 1729, - end: 1736, + start: 1720, + end: 1725, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "select:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "numbers", span: Span { - start: 1737, - end: 1744, + start: 1729, + end: 1736, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 1747, - end: 1748, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "select:", + span: Span { + start: 1737, + end: 1744, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "matchCount", - span: Span { - start: 1755, - end: 1765, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "matchCount", - span: Span { - start: 1769, - end: 1779, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 1782, - end: 1783, - }, - ), - ], - is_cast: false, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "n", span: Span { - start: 1769, - end: 1783, + start: 1747, + end: 1748, }, }, - span: Span { - start: 1755, - end: 1783, - }, - }, - MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "n", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "matchCount", + span: Span { + start: 1755, + end: 1765, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "matchCount", + span: Span { + start: 1769, + end: 1779, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1782, + end: 1783, + }, + ), + ], + is_cast: false, span: Span { - start: 1789, - end: 1790, + start: 1769, + end: 1783, }, }, - ), - selector: Binary( - "%", - ), - arguments: [ - Literal( - Integer( - 2, + span: Span { + start: 1755, + end: 1783, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 1789, + end: 1790, + }, + }, ), - Span { - start: 1793, + selector: Binary( + "%", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1793, + end: 1794, + }, + ), + ], + is_cast: false, + span: Span { + start: 1789, end: 1794, }, + }, + selector: Binary( + "=:=", ), - ], - is_cast: false, - span: Span { - start: 1789, - end: 1794, - }, - }, - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 1799, + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 1799, + end: 1800, + }, + ), + ], + is_cast: false, + span: Span { + start: 1789, end: 1800, }, - ), - ], - is_cast: false, - span: Span { - start: 1789, - end: 1800, + }, }, + ], + span: Span { + start: 1745, + end: 1802, }, - ], - span: Span { - start: 1745, - end: 1802, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1729, + end: 1802, + }, + }, span: Span { - start: 1729, + start: 1720, end: 1802, }, }, - span: Span { - start: 1720, - end: 1802, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "maxSeen", - span: Span { - start: 1888, - end: 1895, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "maxSeen", + span: Span { + start: 1888, + end: 1895, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 1899, + end: 1900, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 1899, + span: Span { + start: 1888, end: 1900, }, - ), - span: Span { - start: 1888, - end: 1900, }, }, - Assignment { - target: Identifier( - Identifier { - name: "finalSum", - span: Span { - start: 1902, - end: 1910, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "numbers", + name: "finalSum", span: Span { - start: 1914, - end: 1921, + start: 1902, + end: 1910, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "inject:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "numbers", span: Span { - start: 1922, - end: 1929, + start: 1914, + end: 1921, }, }, - KeywordPart { - keyword: "into:", - span: Span { - start: 1932, - end: 1937, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "inject:", + span: Span { + start: 1922, + end: 1929, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 1930, - end: 1931, - }, + KeywordPart { + keyword: "into:", + span: Span { + start: 1932, + end: 1937, + }, + }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "acc", - span: Span { - start: 1940, - end: 1943, + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 1930, + end: 1931, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "acc", + span: Span { + start: 1940, + end: 1943, + }, }, - }, - BlockParameter { - name: "n", - span: Span { - start: 1945, - end: 1946, + BlockParameter { + name: "n", + span: Span { + start: 1945, + end: 1946, + }, }, - }, - ], - body: [ - MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "n", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 1953, + end: 1954, + }, + }, + ), + selector: Binary( + ">", + ), + arguments: [ + Identifier( + Identifier { + name: "maxSeen", + span: Span { + start: 1957, + end: 1964, + }, + }, + ), + ], + is_cast: false, span: Span { start: 1953, - end: 1954, + end: 1964, }, }, - ), - selector: Binary( - ">", - ), - arguments: [ - Identifier( - Identifier { - name: "maxSeen", - span: Span { - start: 1957, - end: 1964, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 1965, + end: 1972, + }, }, - }, + ], ), - ], - is_cast: false, - span: Span { - start: 1953, - end: 1964, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 1965, - end: 1972, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "maxSeen", - span: Span { - start: 1974, - end: 1981, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - value: Identifier( - Identifier { - name: "n", - span: Span { - start: 1985, - end: 1986, + expression: Assignment { + target: Identifier( + Identifier { + name: "maxSeen", + span: Span { + start: 1974, + end: 1981, + }, + }, + ), + value: Identifier( + Identifier { + name: "n", + span: Span { + start: 1985, + end: 1986, + }, + }, + ), + span: Span { + start: 1974, + end: 1986, + }, }, }, - ), + ], span: Span { - start: 1974, - end: 1986, + start: 1973, + end: 1987, }, }, - ], - span: Span { - start: 1973, - end: 1987, - }, + ), + ], + is_cast: false, + span: Span { + start: 1953, + end: 1987, }, - ), - ], - is_cast: false, - span: Span { - start: 1953, - end: 1987, + }, }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "acc", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "acc", + span: Span { + start: 1993, + end: 1996, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 1999, + end: 2000, + }, + }, + ), + ], + is_cast: false, span: Span { start: 1993, - end: 1996, + end: 2000, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "n", - span: Span { - start: 1999, - end: 2000, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 1993, - end: 2000, }, + ], + span: Span { + start: 1938, + end: 2002, }, - ], - span: Span { - start: 1938, - end: 2002, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1914, + end: 2002, + }, + }, span: Span { - start: 1914, + start: 1902, end: 2002, }, }, - span: Span { - start: 1902, - end: 2002, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "outerSum", - span: Span { - start: 2197, - end: 2205, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "outerSum", + span: Span { + start: 2197, + end: 2205, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 2209, + end: 2210, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 2209, + span: Span { + start: 2197, end: 2210, }, - ), - span: Span { - start: 2197, - end: 2210, }, }, - Assignment { - target: Identifier( - Identifier { - name: "innerSum", - span: Span { - start: 2212, - end: 2220, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "innerSum", + span: Span { + start: 2212, + end: 2220, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 2224, + end: 2225, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 2224, + span: Span { + start: 2212, end: 2225, }, - ), - span: Span { - start: 2212, - end: 2225, }, }, - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 2227, - end: 2228, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 2227, + end: 2228, + }, + }, + ), + value: Literal( + Integer( + 1, + ), + Span { + start: 2232, + end: 2233, }, - }, - ), - value: Literal( - Integer( - 1, ), - Span { - start: 2232, + span: Span { + start: 2227, end: 2233, }, - ), - span: Span { - start: 2227, - end: 2233, }, }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 2236, - end: 2237, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "<=", - ), - arguments: [ - Literal( - Integer( - 3, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 2236, + end: 2237, + }, + }, + ), + selector: Binary( + "<=", ), - Span { - start: 2241, + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 2241, + end: 2242, + }, + ), + ], + is_cast: false, + span: Span { + start: 2236, end: 2242, }, - ), - ], - is_cast: false, - span: Span { - start: 2236, - end: 2242, + }, }, - }, - ], - span: Span { - start: 2235, - end: 2243, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", + ], span: Span { - start: 2244, - end: 2254, + start: 2235, + end: 2243, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 2261, - end: 2262, - }, - }, - ), - value: Literal( - Integer( - 1, - ), - Span { - start: 2266, - end: 2267, - }, - ), - span: Span { - start: 2261, - end: 2267, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 2244, + end: 2254, }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "y", - span: Span { - start: 2274, - end: 2275, - }, - }, - ), - selector: Binary( - "<=", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 2279, - end: 2280, - }, - ), - ], - is_cast: false, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "y", span: Span { - start: 2274, - end: 2280, + start: 2261, + end: 2262, }, }, - ], + ), + value: Literal( + Integer( + 1, + ), + Span { + start: 2266, + end: 2267, + }, + ), span: Span { - start: 2273, - end: 2281, + start: 2261, + end: 2267, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 2282, - end: 2292, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "innerSum", - span: Span { - start: 2303, - end: 2311, - }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "innerSum", - span: Span { - start: 2315, - end: 2323, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 2326, - end: 2327, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 2274, + end: 2275, + }, }, ), - ], - is_cast: false, - span: Span { - start: 2315, - end: 2327, + selector: Binary( + "<=", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 2279, + end: 2280, + }, + ), + ], + is_cast: false, + span: Span { + start: 2274, + end: 2280, + }, }, }, + ], + span: Span { + start: 2273, + end: 2281, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", span: Span { - start: 2303, - end: 2327, + start: 2282, + end: 2292, }, }, - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 2337, - end: 2338, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "y", + expression: Assignment { + target: Identifier( + Identifier { + name: "innerSum", + span: Span { + start: 2303, + end: 2311, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "innerSum", + span: Span { + start: 2315, + end: 2323, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 2326, + end: 2327, + }, + ), + ], + is_cast: false, + span: Span { + start: 2315, + end: 2327, + }, + }, span: Span { - start: 2342, - end: 2343, + start: 2303, + end: 2327, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "y", + span: Span { + start: 2337, + end: 2338, + }, + }, ), - Span { - start: 2346, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 2342, + end: 2343, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 2346, + end: 2347, + }, + ), + ], + is_cast: false, + span: Span { + start: 2342, + end: 2347, + }, + }, + span: Span { + start: 2337, end: 2347, }, - ), - ], - is_cast: false, - span: Span { - start: 2342, - end: 2347, + }, }, - }, + ], span: Span { - start: 2337, - end: 2347, + start: 2293, + end: 2353, }, }, - ], - span: Span { - start: 2293, - end: 2353, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 2273, - end: 2353, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "outerSum", + ), + ], + is_cast: false, span: Span { - start: 2359, - end: 2367, + start: 2273, + end: 2353, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "outerSum", + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "outerSum", + span: Span { + start: 2359, + end: 2367, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "outerSum", + span: Span { + start: 2371, + end: 2379, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "innerSum", + span: Span { + start: 2382, + end: 2390, + }, + }, + ), + ], + is_cast: false, span: Span { start: 2371, - end: 2379, + end: 2390, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + span: Span { + start: 2359, + end: 2390, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "innerSum", + name: "x", span: Span { - start: 2382, - end: 2390, + start: 2396, + end: 2397, }, }, ), - ], - is_cast: false, - span: Span { - start: 2371, - end: 2390, - }, - }, - span: Span { - start: 2359, - end: 2390, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 2396, - end: 2397, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "x", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 2401, + end: 2402, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 2405, + end: 2406, + }, + ), + ], + is_cast: false, span: Span { start: 2401, - end: 2402, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 2405, end: 2406, }, - ), - ], - is_cast: false, - span: Span { - start: 2401, - end: 2406, + }, + span: Span { + start: 2396, + end: 2406, + }, }, }, - span: Span { - start: 2396, - end: 2406, - }, + ], + span: Span { + start: 2255, + end: 2408, }, - ], - span: Span { - start: 2255, - end: 2408, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 2235, - end: 2408, + ), + ], + is_cast: false, + span: Span { + start: 2235, + end: 2408, + }, }, }, - Error { - message: "Invalid assignment target", - span: Span { - start: 2588, - end: 2595, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Invalid assignment target", + span: Span { + start: 2588, + end: 2595, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 2636, - end: 2637, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 2636, + end: 2637, + }, }, }, - MessageSend { - receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found .", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 2673, + end: 2674, + }, + }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { start: 2673, - end: 2674, + end: 2679, }, }, - selector: Unary( - "value", + selector: Binary( + "<", ), - arguments: [], + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 2682, + end: 2684, + }, + ), + ], is_cast: false, span: Span { start: 2673, - end: 2679, + end: 2684, }, }, - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 10, - ), - Span { - start: 2682, - end: 2684, - }, - ), - ], - is_cast: false, - span: Span { - start: 2673, - end: 2684, - }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 2684, - end: 2685, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 2686, - end: 2696, - }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 2684, + end: 2685, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + }, + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 2686, + end: 2696, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 2711, + end: 2715, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 2716, + end: 2721, + }, + }, span: Span { start: 2711, - end: 2715, + end: 2721, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 2716, - end: 2721, - }, - }, - span: Span { - start: 2711, - end: 2721, - }, - }, - value: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 2725, + end: 2729, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 2730, + end: 2735, + }, + }, span: Span { start: 2725, - end: 2729, + end: 2735, }, }, - ), - field: Identifier { - name: "value", + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 2738, + end: 2739, + }, + ), + ], + is_cast: false, span: Span { - start: 2730, - end: 2735, + start: 2725, + end: 2739, }, }, span: Span { - start: 2725, - end: 2735, + start: 2711, + end: 2739, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 2738, - end: 2739, - }, - ), - ], - is_cast: false, - span: Span { - start: 2725, - end: 2739, - }, - }, - span: Span { - start: 2711, - end: 2739, }, + ], + span: Span { + start: 2697, + end: 2749, }, - ], - span: Span { - start: 2697, - end: 2749, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 2684, - end: 2749, + ), + ], + is_cast: false, + span: Span { + start: 2684, + end: 2749, + }, }, }, - Return { - value: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 2760, + end: 2764, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 2760, - end: 2764, + start: 2765, + end: 2770, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 2765, + start: 2760, end: 2770, }, }, span: Span { - start: 2760, + start: 2759, end: 2770, }, }, - span: Span { - start: 2759, - end: 2770, - }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found incrementBy:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found incrementBy:", + span: Span { + start: 2781, + end: 2793, + }, + }, + selector: Unary( + "amount", + ), + arguments: [], + is_cast: false, span: Span { start: 2781, - end: 2793, + end: 2800, }, }, - selector: Unary( - "amount", - ), - arguments: [], - is_cast: false, - span: Span { - start: 2781, - end: 2800, - }, }, - Error { - message: "Unexpected token: expected expression, found =>", - span: Span { - start: 2801, - end: 2803, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found =>", + span: Span { + start: 2801, + end: 2803, + }, }, }, - Error { - message: "Invalid assignment target", - span: Span { - start: 2850, - end: 2856, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Invalid assignment target", + span: Span { + start: 2850, + end: 2856, + }, }, }, - MessageSend { - receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found .", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 2864, + end: 2865, + }, + }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { start: 2864, - end: 2865, + end: 2870, }, }, - selector: Unary( - "value", + selector: Binary( + "+", ), - arguments: [], + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 2873, + end: 2874, + }, + ), + ], is_cast: false, span: Span { start: 2864, - end: 2870, + end: 2874, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 2873, - end: 2874, - }, - ), - ], - is_cast: false, - span: Span { - start: 2864, - end: 2874, - }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 2883, - end: 2884, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 2883, + end: 2884, + }, }, }, - Return { - value: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 2895, + end: 2899, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 2895, - end: 2899, + start: 2900, + end: 2905, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 2900, + start: 2895, end: 2905, }, }, span: Span { - start: 2895, + start: 2894, end: 2905, }, }, - span: Span { - start: 2894, - end: 2905, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "multiplyFieldWithLoop", + span: Span { + start: 2916, + end: 2937, + }, + }, + ), }, - Identifier( - Identifier { - name: "multiplyFieldWithLoop", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found =>", span: Span { - start: 2916, - end: 2937, + start: 2938, + end: 2940, }, }, - ), - Error { - message: "Unexpected token: expected expression, found =>", - span: Span { - start: 2938, - end: 2940, - }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 2960, - end: 2961, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - MessageSend { - receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 2974, - end: 2975, - }, - }, - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, + expression: Error { + message: "Unexpected token: expected expression, found .", span: Span { - start: 2974, - end: 2980, + start: 2960, + end: 2961, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "timesRepeat:", + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found .", span: Span { - start: 2981, - end: 2993, + start: 2974, + end: 2975, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 3008, - end: 3014, - }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 2974, + end: 2980, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "timesRepeat:", + span: Span { + start: 2981, + end: 2993, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "result", - span: Span { - start: 3018, - end: 3024, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 3008, + end: 3014, + }, }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "result", + span: Span { + start: 3018, + end: 3024, + }, + }, ), - Span { - start: 3027, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 3027, + end: 3028, + }, + ), + ], + is_cast: false, + span: Span { + start: 3018, end: 3028, }, - ), - ], - is_cast: false, - span: Span { - start: 3018, - end: 3028, + }, + span: Span { + start: 3008, + end: 3028, + }, }, }, - span: Span { - start: 3008, - end: 3028, - }, + ], + span: Span { + start: 2994, + end: 3038, }, - ], - span: Span { - start: 2994, - end: 3038, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 2974, - end: 3038, + ), + ], + is_cast: false, + span: Span { + start: 2974, + end: 3038, + }, }, }, - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 3048, + end: 3052, + }, + }, + ), + field: Identifier { + name: "result", span: Span { - start: 3048, - end: 3052, + start: 3053, + end: 3059, }, }, - ), - field: Identifier { - name: "result", span: Span { - start: 3053, + start: 3048, end: 3059, }, }, + value: Identifier( + Identifier { + name: "result", + span: Span { + start: 3063, + end: 3069, + }, + }, + ), span: Span { start: 3048, - end: 3059, + end: 3069, }, }, - value: Identifier( - Identifier { - name: "result", - span: Span { - start: 3063, - end: 3069, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "result", + span: Span { + start: 3080, + end: 3086, + }, }, + ), + span: Span { + start: 3079, + end: 3086, }, - ), - span: Span { - start: 3048, - end: 3069, }, }, - Return { - value: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( Identifier { - name: "result", + name: "complexMutation", span: Span { - start: 3080, - end: 3086, + start: 3097, + end: 3112, }, }, ), - span: Span { - start: 3079, - end: 3086, - }, }, - Identifier( - Identifier { - name: "complexMutation", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found =>", span: Span { - start: 3097, - end: 3112, + start: 3113, + end: 3115, }, }, - ), - Error { - message: "Unexpected token: expected expression, found =>", - span: Span { - start: 3113, - end: 3115, - }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 3177, - end: 3178, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 3177, + end: 3178, + }, }, }, - MessageSend { - receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found .", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 3192, + end: 3193, + }, + }, + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, span: Span { start: 3192, - end: 3193, + end: 3198, }, }, - selector: Unary( - "value", + selector: Binary( + "<", ), - arguments: [], + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 3201, + end: 3202, + }, + ), + ], is_cast: false, span: Span { start: 3192, - end: 3198, + end: 3202, }, }, - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 3201, - end: 3202, - }, - ), - ], - is_cast: false, - span: Span { - start: 3192, - end: 3202, - }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 3202, - end: 3203, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 3204, - end: 3214, - }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 3202, + end: 3203, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + }, + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 3204, + end: 3214, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 3229, + end: 3233, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 3234, + end: 3239, + }, + }, span: Span { start: 3229, - end: 3233, + end: 3239, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 3234, - end: 3239, - }, - }, - span: Span { - start: 3229, - end: 3239, - }, - }, - value: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 3243, + end: 3247, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 3248, + end: 3253, + }, + }, span: Span { start: 3243, - end: 3247, + end: 3253, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 3248, - end: 3253, - }, - }, - span: Span { - start: 3243, - end: 3253, - }, - }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + selector: Binary( + "+", ), - Span { - start: 3256, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 3256, + end: 3257, + }, + ), + ], + is_cast: false, + span: Span { + start: 3243, end: 3257, }, - ), - ], - is_cast: false, - span: Span { - start: 3243, - end: 3257, - }, - }, - span: Span { - start: 3229, - end: 3257, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "temp", + }, span: Span { - start: 3271, - end: 3275, + start: 3229, + end: 3257, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "temp", - span: Span { - start: 3279, - end: 3283, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "temp", + span: Span { + start: 3271, + end: 3275, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - FieldAccess { + ), + value: MessageSend { receiver: Identifier( Identifier { - name: "self", + name: "temp", span: Span { - start: 3286, - end: 3290, + start: 3279, + end: 3283, }, }, ), - field: Identifier { - name: "value", - span: Span { - start: 3291, - end: 3296, + selector: Binary( + "+", + ), + arguments: [ + FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 3286, + end: 3290, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 3291, + end: 3296, + }, + }, + span: Span { + start: 3286, + end: 3296, + }, }, - }, + ], + is_cast: false, span: Span { - start: 3286, + start: 3279, end: 3296, }, }, - ], - is_cast: false, - span: Span { - start: 3279, - end: 3296, + span: Span { + start: 3271, + end: 3296, + }, }, }, - span: Span { - start: 3271, - end: 3296, - }, + ], + span: Span { + start: 3215, + end: 3306, }, - ], + }, + ), + ], + is_cast: false, + span: Span { + start: 3202, + end: 3306, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "temp", span: Span { - start: 3215, - end: 3306, + start: 3317, + end: 3321, }, }, ), - ], - is_cast: false, - span: Span { - start: 3202, - end: 3306, + span: Span { + start: 3316, + end: 3321, + }, }, }, - Return { - value: Identifier( - Identifier { - name: "temp", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found state:", span: Span { - start: 3317, - end: 3321, + start: 3332, + end: 3338, }, }, - ), - span: Span { - start: 3316, - end: 3321, - }, - }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found state:", - span: Span { - start: 3332, - end: 3338, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "result:", - span: Span { - start: 3339, - end: 3346, + selector: Keyword( + [ + KeywordPart { + keyword: "result:", + span: Span { + start: 3339, + end: 3346, + }, }, - }, - ], - ), - arguments: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Integer", + ], + ), + arguments: [ + MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Integer", + span: Span { + start: 3347, + end: 3354, + }, + }, span: Span { start: 3347, end: 3354, }, }, + selector: Binary( + "=", + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 3357, + end: 3358, + }, + ), + ], + is_cast: false, span: Span { start: 3347, - end: 3354, + end: 3358, }, }, - selector: Binary( - "=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 3357, - end: 3358, - }, - ), - ], - is_cast: false, - span: Span { - start: 3347, - end: 3358, - }, + ], + is_cast: false, + span: Span { + start: 3332, + end: 3358, }, - ], - is_cast: false, - span: Span { - start: 3332, - end: 3358, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 3360, - end: 3361, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 3547, - end: 3548, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 3360, + end: 3361, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 3591, - end: 3592, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 3547, + end: 3548, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 3678, - end: 3679, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 3591, + end: 3592, + }, }, }, - Error { - message: "Unexpected token: expected expression, found .", - span: Span { - start: 3686, - end: 3687, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", + span: Span { + start: 3678, + end: 3679, + }, }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found ]", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found .", span: Span { - start: 3694, - end: 3695, + start: 3686, + end: 3687, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 3696, - end: 3706, - }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 3694, + end: 3695, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "a", - span: Span { - start: 3713, - end: 3714, - }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 3696, + end: 3706, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "a", - span: Span { - start: 3718, - end: 3719, + expression: Assignment { + target: Identifier( + Identifier { + name: "a", + span: Span { + start: 3713, + end: 3714, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "a", + span: Span { + start: 3718, + end: 3719, + }, + }, ), - Span { - start: 3722, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 3722, + end: 3723, + }, + ), + ], + is_cast: false, + span: Span { + start: 3718, end: 3723, }, - ), - ], - is_cast: false, - span: Span { - start: 3718, - end: 3723, - }, - }, - span: Span { - start: 3713, - end: 3723, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "b", + }, span: Span { - start: 3729, - end: 3730, + start: 3713, + end: 3723, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "b", - span: Span { - start: 3734, - end: 3735, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "b", + span: Span { + start: 3729, + end: 3730, + }, }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "b", + span: Span { + start: 3734, + end: 3735, + }, + }, ), - Span { - start: 3738, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 3738, + end: 3739, + }, + ), + ], + is_cast: false, + span: Span { + start: 3734, end: 3739, }, - ), - ], - is_cast: false, - span: Span { - start: 3734, - end: 3739, + }, + span: Span { + start: 3729, + end: 3739, + }, }, }, - span: Span { - start: 3729, - end: 3739, - }, + ], + span: Span { + start: 3707, + end: 3741, }, - ], - span: Span { - start: 3707, - end: 3741, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 3694, - end: 3741, + ), + ], + is_cast: false, + span: Span { + start: 3694, + end: 3741, + }, }, }, ], @@ -3038,7 +3572,7 @@ Module { start: 376, end: 3742, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__empty_blocks_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__empty_blocks_parser.snap index 27c8c610c..620bac16a 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__empty_blocks_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__empty_blocks_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,118 +7,142 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "empty", - span: Span { - start: 175, - end: 180, - }, - }, - ), - value: Block( - Block { - parameters: [], - body: [], - span: Span { - start: 184, - end: 186, - }, - }, - ), - span: Span { - start: 175, - end: 186, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Assignment { - target: Identifier( - Identifier { - name: "emptyWithSpace", - span: Span { - start: 221, - end: 235, + expression: Assignment { + target: Identifier( + Identifier { + name: "empty", + span: Span { + start: 175, + end: 180, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [], - span: Span { - start: 239, - end: 242, + ), + value: Block( + Block { + parameters: [], + body: [], + span: Span { + start: 184, + end: 186, + }, }, + ), + span: Span { + start: 175, + end: 186, }, - ), - span: Span { - start: 221, - end: 242, }, }, - Assignment { - target: Identifier( - Identifier { - name: "emptyWithNewlines", - span: Span { - start: 273, - end: 290, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "emptyWithSpace", + span: Span { + start: 221, + end: 235, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [], - span: Span { - start: 294, - end: 298, + ), + value: Block( + Block { + parameters: [], + body: [], + span: Span { + start: 239, + end: 242, + }, }, + ), + span: Span { + start: 221, + end: 242, }, - ), - span: Span { - start: 273, - end: 298, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "collection", - span: Span { - start: 332, - end: 342, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "do:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "emptyWithNewlines", span: Span { - start: 343, - end: 346, + start: 273, + end: 290, }, }, - ], - ), - arguments: [ - Block( + ), + value: Block( Block { parameters: [], body: [], span: Span { - start: 347, - end: 349, + start: 294, + end: 298, }, }, ), - ], - is_cast: false, - span: Span { - start: 332, - end: 349, + span: Span { + start: 273, + end: 298, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "collection", + span: Span { + start: 332, + end: 342, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "do:", + span: Span { + start: 343, + end: 346, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [], + span: Span { + start: 347, + end: 349, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 332, + end: 349, + }, }, }, ], @@ -127,7 +150,7 @@ Module { start: 175, end: 349, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__empty_method_body_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__empty_method_body_parser.snap index c85314aa7..05b813a62 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__empty_method_body_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__empty_method_body_parser.snap @@ -84,27 +84,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 321, + end: 325, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 321, - end: 325, + start: 326, + end: 331, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 326, + start: 321, end: 331, }, }, - span: Span { - start: 321, - end: 331, - }, }, ], return_type: None, @@ -160,7 +166,7 @@ Module { start: 244, end: 354, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__error_message_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__error_message_parser.snap index 4c62c7c35..657a8871f 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__error_message_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__error_message_parser.snap @@ -34,42 +34,48 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 225, - end: 229, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "error:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", span: Span { - start: 230, - end: 236, + start: 225, + end: 229, }, }, - ], - ), - arguments: [ - Literal( - String( - "This is a test error", - ), - Span { - start: 237, - end: 259, - }, ), - ], - is_cast: false, - span: Span { - start: 225, - end: 259, + selector: Keyword( + [ + KeywordPart { + keyword: "error:", + span: Span { + start: 230, + end: 236, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "This is a test error", + ), + Span { + start: 237, + end: 259, + }, + ), + ], + is_cast: false, + span: Span { + start: 225, + end: 259, + }, }, }, ], @@ -92,66 +98,78 @@ Module { ), parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "msg", - span: Span { - start: 291, - end: 294, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "msg", + span: Span { + start: 291, + end: 294, + }, + }, + ), + value: Literal( + String( + "Dynamic error message", + ), + Span { + start: 298, + end: 321, }, - }, - ), - value: Literal( - String( - "Dynamic error message", ), - Span { - start: 298, + span: Span { + start: 291, end: 321, }, - ), - span: Span { - start: 291, - end: 321, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 327, - end: 331, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "error:", - span: Span { - start: 332, - end: 338, - }, - }, - ], - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "msg", + name: "self", span: Span { - start: 339, - end: 342, + start: 327, + end: 331, }, }, ), - ], - is_cast: false, - span: Span { - start: 327, - end: 342, + selector: Keyword( + [ + KeywordPart { + keyword: "error:", + span: Span { + start: 332, + end: 338, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "msg", + span: Span { + start: 339, + end: 342, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 327, + end: 342, + }, }, }, ], @@ -188,7 +206,7 @@ Module { start: 186, end: 342, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_invalid_syntax_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_invalid_syntax_parser.snap index 5565c26c6..124224b5d 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_invalid_syntax_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_invalid_syntax_parser.snap @@ -7,81 +7,111 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "x", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 179, + end: 180, + }, + }, + ), + value: Error { + message: "Unexpected token: expected expression, found :=", span: Span { - start: 179, - end: 180, + start: 184, + end: 186, }, }, - ), - value: Error { - message: "Unexpected token: expected expression, found :=", span: Span { - start: 184, + start: 179, end: 186, }, }, - span: Span { - start: 179, - end: 186, - }, }, - Literal( - Integer( - 5, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 5, + ), + Span { + start: 187, + end: 188, + }, ), - Span { - start: 187, - end: 188, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Assignment { - target: Identifier( - Identifier { - name: "y", + expression: Assignment { + target: Identifier( + Identifier { + name: "y", + span: Span { + start: 209, + end: 210, + }, + }, + ), + value: Error { + message: "Invalid assignment target", span: Span { - start: 209, - end: 210, + start: 214, + end: 251, }, }, - ), - value: Error { - message: "Invalid assignment target", span: Span { - start: 214, + start: 209, end: 251, }, }, - span: Span { - start: 209, - end: 251, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "value", + span: Span { + start: 255, + end: 260, + }, + }, + ), }, - Identifier( - Identifier { - name: "value", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Invalid assignment target", span: Span { - start: 255, - end: 260, + start: 306, + end: 365, }, }, - ), - Error { - message: "Invalid assignment target", - span: Span { - start: 306, - end: 365, - }, }, ], span: Span { start: 179, end: 372, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_malformed_message_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_malformed_message_parser.snap index ea5e1a25e..168a9dcb3 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_malformed_message_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_malformed_message_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,205 +7,235 @@ Module { classes: [], method_definitions: [], expressions: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "dict", - span: Span { - start: 193, - end: 197, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 198, - end: 201, - }, - }, - ], - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "key", + name: "dict", span: Span { - start: 202, - end: 205, + start: 193, + end: 197, }, }, ), - ], - is_cast: false, - span: Span { - start: 193, - end: 205, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "array", - span: Span { - start: 231, - end: 236, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 237, - end: 240, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 198, + end: 201, + }, }, - }, - ], - ), - arguments: [ - MessageSend { - receiver: Identifier( + ], + ), + arguments: [ + Identifier( Identifier { - name: "index", + name: "key", span: Span { - start: 241, - end: 246, + start: 202, + end: 205, }, }, ), - selector: Unary( - "put", - ), - arguments: [], - is_cast: false, - span: Span { - start: 241, - end: 250, - }, + ], + is_cast: false, + span: Span { + start: 193, + end: 205, }, - ], - is_cast: false, - span: Span { - start: 231, - end: 250, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "object", - span: Span { - start: 286, - end: 292, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "foo:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "array", span: Span { - start: 293, - end: 297, + start: 231, + end: 236, }, }, - KeywordPart { - keyword: "bar:", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 237, + end: 240, + }, + }, + ], + ), + arguments: [ + MessageSend { + receiver: Identifier( + Identifier { + name: "index", + span: Span { + start: 241, + end: 246, + }, + }, + ), + selector: Unary( + "put", + ), + arguments: [], + is_cast: false, span: Span { - start: 300, - end: 304, + start: 241, + end: 250, }, }, ], - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 298, - end: 299, + is_cast: false, + span: Span { + start: 231, + end: 250, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "object", + span: Span { + start: 286, + end: 292, + }, }, ), - Error { - message: "Unexpected token: expected expression, found at:", - span: Span { - start: 334, - end: 337, + selector: Keyword( + [ + KeywordPart { + keyword: "foo:", + span: Span { + start: 293, + end: 297, + }, + }, + KeywordPart { + keyword: "bar:", + span: Span { + start: 300, + end: 304, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 298, + end: 299, + }, + ), + Error { + message: "Unexpected token: expected expression, found at:", + span: Span { + start: 334, + end: 337, + }, }, + ], + is_cast: false, + span: Span { + start: 286, + end: 337, }, - ], - is_cast: false, - span: Span { - start: 286, - end: 337, }, }, - Literal( - Integer( - 42, - ), - Span { - start: 338, - end: 340, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 368, - end: 374, - }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 338, + end: 340, }, ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 378, - end: 379, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 368, + end: 374, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( 5, ), Span { - start: 382, - end: 383, + start: 378, + end: 379, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 382, + end: 383, + }, + ), + ], + is_cast: false, + span: Span { + start: 378, + end: 383, + }, + }, span: Span { - start: 378, + start: 368, end: 383, }, }, - span: Span { - start: 368, - end: 383, - }, }, ], span: Span { start: 193, end: 383, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_unterminated_string_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_unterminated_string_parser.snap index a87ddf6b2..a5d2291cf 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_unterminated_string_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__error_recovery_unterminated_string_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,103 +7,115 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "str1", - span: Span { - start: 188, - end: 192, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "str1", + span: Span { + start: 188, + end: 192, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Literal( - String( - "unterminated string\n\n// Code after error should still parse\nx := 42\n\n// Another unterminated string\nstr2 := ", + ), + value: MessageSend { + receiver: MessageSend { + receiver: Literal( + String( + "unterminated string\n\n// Code after error should still parse\nx := 42\n\n// Another unterminated string\nstr2 := ", + ), + Span { + start: 196, + end: 306, + }, + ), + selector: Unary( + "another", ), - Span { + arguments: [], + is_cast: false, + span: Span { start: 196, - end: 306, + end: 313, }, - ), + }, selector: Unary( - "another", + "unclosed", ), arguments: [], is_cast: false, span: Span { start: 196, - end: 313, + end: 322, }, }, - selector: Unary( - "unclosed", - ), - arguments: [], - is_cast: false, span: Span { - start: 196, + start: 188, end: 322, }, }, - span: Span { - start: 188, - end: 322, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 337, - end: 338, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "x", + name: "y", span: Span { - start: 342, - end: 343, + start: 337, + end: 338, }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 346, - end: 347, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 342, + end: 343, + }, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 346, + end: 347, + }, + ), + ], + is_cast: false, + span: Span { + start: 342, + end: 347, + }, + }, span: Span { - start: 342, + start: 337, end: 347, }, }, - span: Span { - start: 337, - end: 347, - }, }, ], span: Span { start: 188, end: 347, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__expect_directive_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__expect_directive_parser.snap index 22855ba9d..8a7998b7a 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__expect_directive_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__expect_directive_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,149 +7,215 @@ Module { classes: [], method_definitions: [], expressions: [ - ExpectDirective { - category: Dnu, - span: Span { - start: 243, - end: 254, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: ExpectDirective { + category: Dnu, + span: Span { + start: 243, + end: 254, + }, }, }, - MessageSend { - receiver: Literal( - Integer( - 42, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 255, + end: 257, + }, ), - Span { + selector: Unary( + "unknownMessage", + ), + arguments: [], + is_cast: false, + span: Span { start: 255, - end: 257, + end: 272, }, - ), - selector: Unary( - "unknownMessage", - ), - arguments: [], - is_cast: false, - span: Span { - start: 255, - end: 272, }, }, - ExpectDirective { - category: Type, - span: Span { - start: 326, - end: 338, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: ExpectDirective { + category: Type, + span: Span { + start: 326, + end: 338, + }, }, }, - MessageSend { - receiver: Literal( - Integer( - 42, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 339, + end: 341, + }, ), - Span { + selector: Binary( + "+", + ), + arguments: [ + Literal( + String( + "hello", + ), + Span { + start: 344, + end: 351, + }, + ), + ], + is_cast: false, + span: Span { start: 339, - end: 341, + end: 351, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - String( - "hello", + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: ExpectDirective { + category: Unused, + span: Span { + start: 409, + end: 423, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "tempVar", + span: Span { + start: 424, + end: 431, + }, + }, + ), + value: Literal( + Integer( + 99, ), Span { - start: 344, - end: 351, + start: 435, + end: 437, }, ), - ], - is_cast: false, - span: Span { - start: 339, - end: 351, + span: Span { + start: 424, + end: 437, + }, }, }, - ExpectDirective { - category: Unused, - span: Span { - start: 409, - end: 423, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: ExpectDirective { + category: All, + span: Span { + start: 482, + end: 493, + }, }, }, - Assignment { - target: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( Identifier { - name: "tempVar", + name: "someUndefinedMethod", span: Span { - start: 424, - end: 431, + start: 494, + end: 513, }, }, ), - value: Literal( - Integer( - 99, - ), - Span { - start: 435, - end: 437, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: ExpectDirective { + category: Dnu, + span: Span { + start: 587, + end: 598, }, - ), - span: Span { - start: 424, - end: 437, }, }, - ExpectDirective { - category: All, - span: Span { - start: 482, - end: 493, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Identifier( - Identifier { - name: "someUndefinedMethod", + expression: ExpectDirective { + category: Type, span: Span { - start: 494, - end: 513, + start: 599, + end: 611, }, }, - ), - ExpectDirective { - category: Dnu, - span: Span { - start: 587, - end: 598, - }, }, - ExpectDirective { - category: Type, - span: Span { - start: 599, - end: 611, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - MessageSend { - receiver: Literal( - Integer( - 42, + expression: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 612, + end: 614, + }, + ), + selector: Unary( + "unknownMessage", ), - Span { + arguments: [], + is_cast: false, + span: Span { start: 612, - end: 614, + end: 629, }, - ), - selector: Unary( - "unknownMessage", - ), - arguments: [], - is_cast: false, - span: Span { - start: 612, - end: 629, }, }, ], @@ -158,7 +223,7 @@ Module { start: 243, end: 629, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__future_pattern_matching_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__future_pattern_matching_parser.snap index 93d51e692..d3c3b9791 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__future_pattern_matching_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__future_pattern_matching_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,311 +7,467 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 268, - end: 274, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 268, + end: 274, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "match", - span: Span { - start: 278, - end: 283, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "match", + span: Span { + start: 278, + end: 283, + }, }, + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 278, + end: 289, }, - ), + }, selector: Unary( - "value", + "with", ), arguments: [], is_cast: false, span: Span { start: 278, - end: 289, + end: 294, }, }, - selector: Unary( - "with", - ), - arguments: [], - is_cast: false, span: Span { - start: 278, + start: 268, end: 294, }, }, - span: Span { - start: 268, - end: 294, - }, }, - Error { - message: "Unexpected token: expected expression, found |", - span: Span { - start: 297, - end: 298, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found |", + span: Span { + start: 297, + end: 298, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 558, - end: 559, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 558, + end: 559, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 581, - end: 582, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 581, + end: 582, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 614, - end: 615, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 614, + end: 615, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 647, - end: 648, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 647, + end: 648, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 767, - end: 768, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 767, + end: 768, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 819, - end: 820, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 819, + end: 820, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 866, - end: 867, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 866, + end: 867, + }, }, }, - MessageSend { - receiver: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found )", + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 993, + end: 994, + }, + }, + selector: Unary( + "when", + ), + arguments: [], + is_cast: false, span: Span { start: 993, - end: 994, + end: 999, }, }, selector: Unary( - "when", + "r", ), arguments: [], is_cast: false, span: Span { start: 993, - end: 999, + end: 1001, }, }, - selector: Unary( - "r", + selector: Binary( + ">", ), - arguments: [], + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 1004, + end: 1006, + }, + ), + ], is_cast: false, span: Span { start: 993, - end: 1001, + end: 1006, }, }, - selector: Binary( - ">", - ), - arguments: [ - Literal( - Integer( - 10, - ), - Span { - start: 1004, - end: 1006, - }, - ), - ], - is_cast: false, - span: Span { - start: 993, - end: 1006, - }, }, - Error { - message: "Unexpected token: expected expression, found =>", - span: Span { - start: 1007, - end: 1009, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found =>", + span: Span { + start: 1007, + end: 1009, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 1045, - end: 1046, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 1045, + end: 1046, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 1102, - end: 1103, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 1102, + end: 1103, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 1247, - end: 1248, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 1247, + end: 1248, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 1282, - end: 1283, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 1282, + end: 1283, + }, }, }, - Error { - message: "Unexpected token: expected expression, found )", - span: Span { - start: 1319, - end: 1320, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found )", + span: Span { + start: 1319, + end: 1320, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 1476, - end: 1477, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 1476, + end: 1477, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 1514, - end: 1515, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 1514, + end: 1515, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 1683, - end: 1684, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 1683, + end: 1684, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 1907, - end: 1908, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 1907, + end: 1908, + }, }, }, - MessageSend { - receiver: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found }", + receiver: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 1919, + end: 1920, + }, + }, + selector: Unary( + "when", + ), + arguments: [], + is_cast: false, span: Span { start: 1919, - end: 1920, + end: 1925, }, }, selector: Unary( - "when", + "n", ), arguments: [], is_cast: false, span: Span { start: 1919, - end: 1925, + end: 1927, }, }, - selector: Unary( - "n", + selector: Binary( + ">", ), - arguments: [], + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 1930, + end: 1931, + }, + ), + ], is_cast: false, span: Span { start: 1919, - end: 1927, + end: 1931, }, }, - selector: Binary( - ">", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 1930, - end: 1931, - }, - ), - ], - is_cast: false, - span: Span { - start: 1919, - end: 1931, - }, }, - Error { - message: "Unexpected token: expected expression, found =>", - span: Span { - start: 1932, - end: 1934, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found =>", + span: Span { + start: 1932, + end: 1934, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 2021, - end: 2022, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 2021, + end: 2022, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 2033, - end: 2034, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 2033, + end: 2034, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 2081, - end: 2082, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 2081, + end: 2082, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 2093, - end: 2094, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 2093, + end: 2094, + }, }, }, ], @@ -320,7 +475,7 @@ Module { start: 268, end: 2150, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__future_string_interpolation_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__future_string_interpolation_parser.snap index 733d59f1a..d349575d1 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__future_string_interpolation_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__future_string_interpolation_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,552 +7,642 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "name", - span: Span { - start: 164, - end: 168, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "name", + span: Span { + start: 164, + end: 168, + }, }, - }, - ), - value: Literal( - String( - "Alice", ), - Span { - start: 172, + value: Literal( + String( + "Alice", + ), + Span { + start: 172, + end: 179, + }, + ), + span: Span { + start: 164, end: 179, }, - ), - span: Span { - start: 164, - end: 179, }, }, - Assignment { - target: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 180, - end: 188, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 180, + end: 188, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "Hello, ", - ), - Interpolation( - Identifier( - Identifier { - name: "name", - span: Span { - start: 201, - end: 205, + ), + value: StringInterpolation { + segments: [ + Literal( + "Hello, ", + ), + Interpolation( + Identifier( + Identifier { + name: "name", + span: Span { + start: 201, + end: 205, + }, }, - }, + ), ), - ), - Literal( - "!", - ), - ], + Literal( + "!", + ), + ], + span: Span { + start: 192, + end: 208, + }, + }, span: Span { - start: 192, + start: 180, end: 208, }, }, - span: Span { - start: 180, - end: 208, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "age", - span: Span { - start: 238, - end: 241, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "age", + span: Span { + start: 238, + end: 241, + }, + }, + ), + value: Literal( + Integer( + 25, + ), + Span { + start: 245, + end: 247, }, - }, - ), - value: Literal( - Integer( - 25, ), - Span { - start: 245, + span: Span { + start: 238, end: 247, }, - ), - span: Span { - start: 238, - end: 247, }, }, - Assignment { - target: Identifier( - Identifier { - name: "message", - span: Span { - start: 248, - end: 255, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "message", + span: Span { + start: 248, + end: 255, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "You are ", - ), - Interpolation( - MessageSend { - receiver: Identifier( - Identifier { - name: "age", - span: Span { - start: 269, - end: 272, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 275, - end: 276, + ), + value: StringInterpolation { + segments: [ + Literal( + "You are ", + ), + Interpolation( + MessageSend { + receiver: Identifier( + Identifier { + name: "age", + span: Span { + start: 269, + end: 272, + }, }, ), - ], - is_cast: false, - span: Span { - start: 269, - end: 276, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 275, + end: 276, + }, + ), + ], + is_cast: false, + span: Span { + start: 269, + end: 276, + }, }, - }, - ), - Literal( - " years old in 5 years", - ), - ], + ), + Literal( + " years old in 5 years", + ), + ], + span: Span { + start: 259, + end: 299, + }, + }, span: Span { - start: 259, + start: 248, end: 299, }, }, - span: Span { - start: 248, - end: 299, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "firstName", - span: Span { - start: 342, - end: 351, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "firstName", + span: Span { + start: 342, + end: 351, + }, + }, + ), + value: Literal( + String( + "Bob", + ), + Span { + start: 355, + end: 360, }, - }, - ), - value: Literal( - String( - "Bob", ), - Span { - start: 355, + span: Span { + start: 342, end: 360, }, - ), - span: Span { - start: 342, - end: 360, }, }, - Assignment { - target: Identifier( - Identifier { - name: "lastName", - span: Span { - start: 361, - end: 369, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "lastName", + span: Span { + start: 361, + end: 369, + }, }, - }, - ), - value: Literal( - String( - "Smith", ), - Span { - start: 373, + value: Literal( + String( + "Smith", + ), + Span { + start: 373, + end: 380, + }, + ), + span: Span { + start: 361, end: 380, }, - ), - span: Span { - start: 361, - end: 380, }, }, - Assignment { - target: Identifier( - Identifier { - name: "fullName", - span: Span { - start: 381, - end: 389, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "fullName", + span: Span { + start: 381, + end: 389, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "Name: ", - ), - Interpolation( - Identifier( - Identifier { - name: "firstName", - span: Span { - start: 401, - end: 410, + ), + value: StringInterpolation { + segments: [ + Literal( + "Name: ", + ), + Interpolation( + Identifier( + Identifier { + name: "firstName", + span: Span { + start: 401, + end: 410, + }, }, - }, + ), ), - ), - Literal( - " ", - ), - Interpolation( - Identifier( - Identifier { - name: "lastName", - span: Span { - start: 413, - end: 421, + Literal( + " ", + ), + Interpolation( + Identifier( + Identifier { + name: "lastName", + span: Span { + start: 413, + end: 421, + }, }, - }, + ), ), - ), - ], + ], + span: Span { + start: 393, + end: 423, + }, + }, span: Span { - start: 393, + start: 381, end: 423, }, }, - span: Span { - start: 381, - end: 423, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "escaped", - span: Span { - start: 469, - end: 476, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "escaped", + span: Span { + start: 469, + end: 476, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "Literal braces: \\{ and \\}, variable: ", - ), - Interpolation( - Identifier( - Identifier { - name: "name", - span: Span { - start: 519, - end: 523, + ), + value: StringInterpolation { + segments: [ + Literal( + "Literal braces: \\{ and \\}, variable: ", + ), + Interpolation( + Identifier( + Identifier { + name: "name", + span: Span { + start: 519, + end: 523, + }, }, - }, + ), ), - ), - ], + ], + span: Span { + start: 480, + end: 525, + }, + }, span: Span { - start: 480, + start: 469, end: 525, }, }, - span: Span { - start: 469, - end: 525, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "emojiVar", - span: Span { - start: 562, - end: 570, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "emojiVar", + span: Span { + start: 562, + end: 570, + }, }, - }, - ), - value: Literal( - String( - "🎉", ), - Span { - start: 574, + value: Literal( + String( + "🎉", + ), + Span { + start: 574, + end: 580, + }, + ), + span: Span { + start: 562, end: 580, }, - ), - span: Span { - start: 562, - end: 580, }, }, - Assignment { - target: Identifier( - Identifier { - name: "withEmoji", - span: Span { - start: 581, - end: 590, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "withEmoji", + span: Span { + start: 581, + end: 590, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "Celebration: ", - ), - Interpolation( - Identifier( - Identifier { - name: "emojiVar", - span: Span { - start: 609, - end: 617, + ), + value: StringInterpolation { + segments: [ + Literal( + "Celebration: ", + ), + Interpolation( + Identifier( + Identifier { + name: "emojiVar", + span: Span { + start: 609, + end: 617, + }, }, - }, + ), ), - ), - Literal( - " ", - ), - Interpolation( - Identifier( - Identifier { - name: "name", - span: Span { - start: 620, - end: 624, + Literal( + " ", + ), + Interpolation( + Identifier( + Identifier { + name: "name", + span: Span { + start: 620, + end: 624, + }, }, - }, + ), ), - ), - Literal( - "!", - ), - ], + Literal( + "!", + ), + ], + span: Span { + start: 594, + end: 627, + }, + }, span: Span { - start: 594, + start: 581, end: 627, }, }, - span: Span { - start: 581, - end: 627, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "count", - span: Span { - start: 663, - end: 668, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "count", + span: Span { + start: 663, + end: 668, + }, + }, + ), + value: Literal( + Integer( + 10, + ), + Span { + start: 672, + end: 674, }, - }, - ), - value: Literal( - Integer( - 10, ), - Span { - start: 672, + span: Span { + start: 663, end: 674, }, - ), - span: Span { - start: 663, - end: 674, }, }, - Assignment { - target: Identifier( - Identifier { - name: "summary", - span: Span { - start: 675, - end: 682, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "summary", + span: Span { + start: 675, + end: 682, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Literal( - "Total: ", - ), - Interpolation( - MessageSend { - receiver: Identifier( - Identifier { - name: "count", - span: Span { - start: 695, - end: 700, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 703, - end: 704, + ), + value: StringInterpolation { + segments: [ + Literal( + "Total: ", + ), + Interpolation( + MessageSend { + receiver: Identifier( + Identifier { + name: "count", + span: Span { + start: 695, + end: 700, + }, }, ), - ], - is_cast: false, - span: Span { - start: 695, - end: 704, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 703, + end: 704, + }, + ), + ], + is_cast: false, + span: Span { + start: 695, + end: 704, + }, }, - }, - ), - ], + ), + ], + span: Span { + start: 686, + end: 706, + }, + }, span: Span { - start: 686, + start: 675, end: 706, }, }, - span: Span { - start: 675, - end: 706, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "adjacent", - span: Span { - start: 735, - end: 743, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "adjacent", + span: Span { + start: 735, + end: 743, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Interpolation( - Identifier( - Identifier { - name: "firstName", - span: Span { - start: 749, - end: 758, + ), + value: StringInterpolation { + segments: [ + Interpolation( + Identifier( + Identifier { + name: "firstName", + span: Span { + start: 749, + end: 758, + }, }, - }, + ), ), - ), - Interpolation( - Identifier( - Identifier { - name: "lastName", - span: Span { - start: 760, - end: 768, + Interpolation( + Identifier( + Identifier { + name: "lastName", + span: Span { + start: 760, + end: 768, + }, }, - }, + ), ), - ), - ], + ], + span: Span { + start: 747, + end: 770, + }, + }, span: Span { - start: 747, + start: 735, end: 770, }, }, - span: Span { - start: 735, - end: 770, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "bare", - span: Span { - start: 816, - end: 820, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "bare", + span: Span { + start: 816, + end: 820, + }, }, - }, - ), - value: StringInterpolation { - segments: [ - Interpolation( - Identifier( - Identifier { - name: "name", - span: Span { - start: 826, - end: 830, + ), + value: StringInterpolation { + segments: [ + Interpolation( + Identifier( + Identifier { + name: "name", + span: Span { + start: 826, + end: 830, + }, }, - }, + ), ), - ), - ], + ], + span: Span { + start: 824, + end: 832, + }, + }, span: Span { - start: 824, + start: 816, end: 832, }, }, - span: Span { - start: 816, - end: 832, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "plain", - span: Span { - start: 884, - end: 889, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "plain", + span: Span { + start: 884, + end: 889, + }, + }, + ), + value: Literal( + String( + "Hello, World!", + ), + Span { + start: 893, + end: 908, }, - }, - ), - value: Literal( - String( - "Hello, World!", ), - Span { - start: 893, + span: Span { + start: 884, end: 908, }, - ), - span: Span { - start: 884, - end: 908, }, }, ], @@ -561,7 +650,7 @@ Module { start: 164, end: 908, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__hello_world_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__hello_world_parser.snap index d8cb33c82..eda4b7cc9 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__hello_world_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__hello_world_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,54 +7,60 @@ Module { classes: [], method_definitions: [], expressions: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 133, + end: 143, + }, + }, span: Span { start: 133, end: 143, }, }, + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 144, + end: 149, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "Hello, World!", + ), + Span { + start: 150, + end: 165, + }, + ), + ], + is_cast: false, span: Span { start: 133, - end: 143, + end: 165, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 144, - end: 149, - }, - }, - ], - ), - arguments: [ - Literal( - String( - "Hello, World!", - ), - Span { - start: 150, - end: 165, - }, - ), - ], - is_cast: false, - span: Span { - start: 133, - end: 165, - }, }, ], span: Span { start: 133, end: 165, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__intrinsic_keyword_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__intrinsic_keyword_parser.snap index dfb5fe911..92fb74823 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__intrinsic_keyword_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__intrinsic_keyword_parser.snap @@ -34,12 +34,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "blockValue", - is_quoted: false, - span: Span { - start: 241, - end: 262, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "blockValue", + is_quoted: false, + span: Span { + start: 241, + end: 262, + }, }, }, ], @@ -62,12 +68,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "size", - is_quoted: true, - span: Span { - start: 273, - end: 290, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "size", + is_quoted: true, + span: Span { + start: 273, + end: 290, + }, }, }, ], @@ -104,7 +116,7 @@ Module { start: 204, end: 290, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__map_literals_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__map_literals_parser.snap index e005ed64d..c6db22ebe 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__map_literals_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__map_literals_parser.snap @@ -7,649 +7,697 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "empty", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "empty", + span: Span { + start: 119, + end: 124, + }, + }, + ), + value: MapLiteral { + pairs: [], span: Span { - start: 119, - end: 124, + start: 128, + end: 131, }, }, - ), - value: MapLiteral { - pairs: [], span: Span { - start: 128, + start: 119, end: 131, }, }, - span: Span { - start: 119, - end: 131, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "person", - span: Span { - start: 155, - end: 161, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "person", + span: Span { + start: 155, + end: 161, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "name", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "name", + ), + Span { + start: 167, + end: 172, + }, ), - Span { - start: 167, - end: 172, - }, - ), - value: Literal( - String( - "Alice", + value: Literal( + String( + "Alice", + ), + Span { + start: 176, + end: 183, + }, ), - Span { - start: 176, + span: Span { + start: 167, end: 183, }, - ), - span: Span { - start: 167, - end: 183, }, - }, - MapPair { - key: Literal( - Symbol( - "age", + MapPair { + key: Literal( + Symbol( + "age", + ), + Span { + start: 185, + end: 189, + }, ), - Span { - start: 185, - end: 189, - }, - ), - value: Literal( - Integer( - 30, + value: Literal( + Integer( + 30, + ), + Span { + start: 193, + end: 195, + }, ), - Span { - start: 193, + span: Span { + start: 185, end: 195, }, - ), - span: Span { - start: 185, - end: 195, }, + ], + span: Span { + start: 165, + end: 196, }, - ], + }, span: Span { - start: 165, + start: 155, end: 196, }, }, - span: Span { - start: 155, - end: 196, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "config", - span: Span { - start: 222, - end: 228, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "config", + span: Span { + start: 222, + end: 228, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - String( - "host", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + String( + "host", + ), + Span { + start: 234, + end: 240, + }, ), - Span { - start: 234, - end: 240, - }, - ), - value: Literal( - String( - "localhost", + value: Literal( + String( + "localhost", + ), + Span { + start: 244, + end: 255, + }, ), - Span { - start: 244, + span: Span { + start: 234, end: 255, }, - ), - span: Span { - start: 234, - end: 255, }, - }, - MapPair { - key: Literal( - String( - "port", + MapPair { + key: Literal( + String( + "port", + ), + Span { + start: 257, + end: 263, + }, ), - Span { - start: 257, - end: 263, - }, - ), - value: Literal( - Integer( - 8080, + value: Literal( + Integer( + 8080, + ), + Span { + start: 267, + end: 271, + }, ), - Span { - start: 267, + span: Span { + start: 257, end: 271, }, - ), - span: Span { - start: 257, - end: 271, }, + ], + span: Span { + start: 232, + end: 272, }, - ], + }, span: Span { - start: 232, + start: 222, end: 272, }, }, - span: Span { - start: 222, - end: 272, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "positions", - span: Span { - start: 299, - end: 308, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "positions", + span: Span { + start: 299, + end: 308, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Integer( - 1, + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Integer( + 1, + ), + Span { + start: 314, + end: 315, + }, ), - Span { - start: 314, - end: 315, - }, - ), - value: Literal( - String( - "first", + value: Literal( + String( + "first", + ), + Span { + start: 319, + end: 326, + }, ), - Span { - start: 319, + span: Span { + start: 314, end: 326, }, - ), - span: Span { - start: 314, - end: 326, }, - }, - MapPair { - key: Literal( - Integer( - 2, + MapPair { + key: Literal( + Integer( + 2, + ), + Span { + start: 328, + end: 329, + }, ), - Span { - start: 328, - end: 329, - }, - ), - value: Literal( - String( - "second", + value: Literal( + String( + "second", + ), + Span { + start: 333, + end: 341, + }, ), - Span { - start: 333, + span: Span { + start: 328, end: 341, }, - ), - span: Span { - start: 328, - end: 341, }, - }, - MapPair { - key: Literal( - Integer( - 3, + MapPair { + key: Literal( + Integer( + 3, + ), + Span { + start: 343, + end: 344, + }, ), - Span { - start: 343, - end: 344, - }, - ), - value: Literal( - String( - "third", + value: Literal( + String( + "third", + ), + Span { + start: 348, + end: 355, + }, ), - Span { - start: 348, + span: Span { + start: 343, end: 355, }, - ), - span: Span { - start: 343, - end: 355, }, + ], + span: Span { + start: 312, + end: 356, }, - ], + }, span: Span { - start: 312, + start: 299, end: 356, }, }, - span: Span { - start: 299, - end: 356, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "mixed", - span: Span { - start: 386, - end: 391, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "mixed", + span: Span { + start: 386, + end: 391, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "type", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "type", + ), + Span { + start: 397, + end: 402, + }, ), - Span { - start: 397, - end: 402, - }, - ), - value: Literal( - String( - "mixed", + value: Literal( + String( + "mixed", + ), + Span { + start: 406, + end: 413, + }, ), - Span { - start: 406, + span: Span { + start: 397, end: 413, }, - ), - span: Span { - start: 397, - end: 413, }, - }, - MapPair { - key: Literal( - String( - "count", + MapPair { + key: Literal( + String( + "count", + ), + Span { + start: 415, + end: 422, + }, ), - Span { - start: 415, - end: 422, - }, - ), - value: Literal( - Integer( - 5, + value: Literal( + Integer( + 5, + ), + Span { + start: 426, + end: 427, + }, ), - Span { - start: 426, + span: Span { + start: 415, end: 427, }, - ), - span: Span { - start: 415, - end: 427, }, - }, - MapPair { - key: Literal( - Integer( - 42, + MapPair { + key: Literal( + Integer( + 42, + ), + Span { + start: 429, + end: 431, + }, ), - Span { - start: 429, - end: 431, - }, - ), - value: Literal( - String( - "answer", + value: Literal( + String( + "answer", + ), + Span { + start: 435, + end: 443, + }, ), - Span { - start: 435, + span: Span { + start: 429, end: 443, }, - ), - span: Span { - start: 429, - end: 443, }, + ], + span: Span { + start: 395, + end: 444, }, - ], + }, span: Span { - start: 395, + start: 386, end: 444, }, }, - span: Span { - start: 386, - end: 444, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "data", - span: Span { - start: 461, - end: 465, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "data", + span: Span { + start: 461, + end: 465, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "user", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "user", + ), + Span { + start: 474, + end: 479, + }, ), - Span { - start: 474, - end: 479, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "name", + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "name", + ), + Span { + start: 490, + end: 495, + }, ), - Span { - start: 490, - end: 495, - }, - ), - value: Literal( - String( - "Bob", + value: Literal( + String( + "Bob", + ), + Span { + start: 499, + end: 504, + }, ), - Span { - start: 499, + span: Span { + start: 490, end: 504, }, - ), - span: Span { - start: 490, - end: 504, }, - }, - MapPair { - key: Literal( - Symbol( - "email", + MapPair { + key: Literal( + Symbol( + "email", + ), + Span { + start: 510, + end: 516, + }, ), - Span { - start: 510, - end: 516, - }, - ), - value: Literal( - String( - "bob@example.com", + value: Literal( + String( + "bob@example.com", + ), + Span { + start: 520, + end: 537, + }, ), - Span { - start: 520, + span: Span { + start: 510, end: 537, }, - ), - span: Span { - start: 510, - end: 537, }, + ], + span: Span { + start: 483, + end: 541, }, - ], + }, span: Span { - start: 483, + start: 474, end: 541, }, }, - span: Span { - start: 474, - end: 541, - }, - }, - MapPair { - key: Literal( - Symbol( - "settings", + MapPair { + key: Literal( + Symbol( + "settings", + ), + Span { + start: 545, + end: 554, + }, ), - Span { - start: 545, - end: 554, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "theme", + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "theme", + ), + Span { + start: 565, + end: 571, + }, ), - Span { - start: 565, - end: 571, - }, - ), - value: Literal( - String( - "dark", + value: Literal( + String( + "dark", + ), + Span { + start: 575, + end: 581, + }, ), - Span { - start: 575, + span: Span { + start: 565, end: 581, }, - ), - span: Span { - start: 565, - end: 581, }, - }, - MapPair { - key: Literal( - Symbol( - "language", + MapPair { + key: Literal( + Symbol( + "language", + ), + Span { + start: 587, + end: 596, + }, ), - Span { - start: 587, - end: 596, - }, - ), - value: Literal( - String( - "en", + value: Literal( + String( + "en", + ), + Span { + start: 600, + end: 604, + }, ), - Span { - start: 600, + span: Span { + start: 587, end: 604, }, - ), - span: Span { - start: 587, - end: 604, }, + ], + span: Span { + start: 558, + end: 608, }, - ], + }, span: Span { - start: 558, + start: 545, end: 608, }, }, - span: Span { - start: 545, - end: 608, - }, + ], + span: Span { + start: 469, + end: 610, }, - ], + }, span: Span { - start: 469, + start: 461, end: 610, }, }, - span: Span { - start: 461, - end: 610, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "withTrailing", - span: Span { - start: 639, - end: 651, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "withTrailing", + span: Span { + start: 639, + end: 651, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "a", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "a", + ), + Span { + start: 657, + end: 659, + }, ), - Span { - start: 657, - end: 659, - }, - ), - value: Literal( - Integer( - 1, + value: Literal( + Integer( + 1, + ), + Span { + start: 663, + end: 664, + }, ), - Span { - start: 663, + span: Span { + start: 657, end: 664, }, - ), - span: Span { - start: 657, - end: 664, }, - }, - MapPair { - key: Literal( - Symbol( - "b", + MapPair { + key: Literal( + Symbol( + "b", + ), + Span { + start: 666, + end: 668, + }, ), - Span { - start: 666, - end: 668, - }, - ), - value: Literal( - Integer( - 2, + value: Literal( + Integer( + 2, + ), + Span { + start: 672, + end: 673, + }, ), - Span { - start: 672, + span: Span { + start: 666, end: 673, }, - ), - span: Span { - start: 666, - end: 673, }, + ], + span: Span { + start: 655, + end: 675, }, - ], + }, span: Span { - start: 655, + start: 639, end: 675, }, }, - span: Span { - start: 639, - end: 675, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "single", - span: Span { - start: 697, - end: 703, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "single", + span: Span { + start: 697, + end: 703, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "only", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "only", + ), + Span { + start: 709, + end: 714, + }, ), - Span { - start: 709, - end: 714, - }, - ), - value: Literal( - String( - "value", + value: Literal( + String( + "value", + ), + Span { + start: 718, + end: 725, + }, ), - Span { - start: 718, + span: Span { + start: 709, end: 725, }, - ), - span: Span { - start: 709, - end: 725, }, + ], + span: Span { + start: 707, + end: 726, }, - ], + }, span: Span { - start: 707, + start: 697, end: 726, }, }, - span: Span { - start: 697, - end: 726, - }, }, ], span: Span { start: 119, end: 726, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__method_lookup_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__method_lookup_parser.snap index ab5f4f9b2..07eda03ad 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__method_lookup_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__method_lookup_parser.snap @@ -34,39 +34,45 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Counter", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Counter", + span: Span { + start: 396, + end: 403, + }, + }, span: Span { start: 396, end: 403, }, }, + selector: Binary( + ">>", + ), + arguments: [ + Literal( + Symbol( + "increment", + ), + Span { + start: 407, + end: 417, + }, + ), + ], + is_cast: false, span: Span { start: 396, - end: 403, + end: 417, }, }, - selector: Binary( - ">>", - ), - arguments: [ - Literal( - Symbol( - "increment", - ), - Span { - start: 407, - end: 417, - }, - ), - ], - is_cast: false, - span: Span { - start: 396, - end: 417, - }, }, ], return_type: None, @@ -107,34 +113,40 @@ Module { }, ], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "cls", - span: Span { - start: 518, - end: 521, - }, - }, - ), - selector: Binary( - ">>", - ), - arguments: [ - Literal( - Symbol( - "getValue", - ), - Span { - start: 525, - end: 534, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "cls", + span: Span { + start: 518, + end: 521, + }, }, ), - ], - is_cast: false, - span: Span { - start: 518, - end: 534, + selector: Binary( + ">>", + ), + arguments: [ + Literal( + Symbol( + "getValue", + ), + Span { + start: 525, + end: 534, + }, + ), + ], + is_cast: false, + span: Span { + start: 518, + end: 534, + }, }, }, ], @@ -171,7 +183,7 @@ Module { start: 286, end: 534, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__multi_keyword_complex_args_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__multi_keyword_complex_args_parser.snap index 1ef4be1c3..1540e7841 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__multi_keyword_complex_args_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__multi_keyword_complex_args_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,108 +7,269 @@ Module { classes: [], method_definitions: [], expressions: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "array", - span: Span { - start: 189, - end: 194, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "with:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "array", span: Span { - start: 195, - end: 200, + start: 189, + end: 194, }, }, - KeywordPart { - keyword: "and:", - span: Span { - start: 214, - end: 218, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "with:", + span: Span { + start: 195, + end: 200, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 203, - end: 204, - }, + KeywordPart { + keyword: "and:", + span: Span { + start: 214, + end: 218, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 203, + end: 204, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 207, + end: 208, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 211, + end: 212, + }, + ), + ], + is_cast: false, span: Span { start: 207, - end: 208, + end: 212, }, }, + }, + ], + span: Span { + start: 201, + end: 213, + }, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "y", + span: Span { + start: 221, + end: 222, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 225, + end: 226, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 229, + end: 230, + }, + ), + ], + is_cast: false, + span: Span { + start: 225, + end: 230, + }, + }, + }, + ], + span: Span { + start: 219, + end: 231, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 189, + end: 231, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "calculator", + span: Span { + start: 262, + end: 272, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "compute:", + span: Span { + start: 273, + end: 281, + }, + }, + KeywordPart { + keyword: "with:", + span: Span { + start: 292, + end: 297, + }, + }, + ], + ), + arguments: [ + MessageSend { + receiver: Literal( + Integer( + 2, + ), + Span { + start: 282, + end: 283, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + MessageSend { + receiver: Literal( + Integer( + 3, + ), + Span { + start: 286, + end: 287, + }, ), selector: Binary( - "+", + "*", ), arguments: [ Literal( Integer( - 1, + 4, ), Span { - start: 211, - end: 212, + start: 290, + end: 291, }, ), ], is_cast: false, span: Span { - start: 207, - end: 212, + start: 286, + end: 291, }, }, ], + is_cast: false, span: Span { - start: 201, - end: 213, + start: 282, + end: 291, }, }, - ), - Block( - Block { - parameters: [ - BlockParameter { - name: "y", - span: Span { - start: 221, - end: 222, - }, + MessageSend { + receiver: Literal( + Integer( + 10, + ), + Span { + start: 298, + end: 300, }, - ], - body: [ + ), + selector: Binary( + "-", + ), + arguments: [ MessageSend { - receiver: Identifier( - Identifier { - name: "y", - span: Span { - start: 225, - end: 226, - }, + receiver: Literal( + Integer( + 5, + ), + Span { + start: 303, + end: 304, }, ), selector: Binary( - "*", + "/", ), arguments: [ Literal( @@ -117,447 +277,328 @@ Module { 2, ), Span { - start: 229, - end: 230, + start: 307, + end: 308, }, ), ], is_cast: false, span: Span { - start: 225, - end: 230, + start: 303, + end: 308, }, }, ], + is_cast: false, span: Span { - start: 219, - end: 231, + start: 298, + end: 308, }, }, - ), - ], - is_cast: false, - span: Span { - start: 189, - end: 231, + ], + is_cast: false, + span: Span { + start: 262, + end: 308, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "calculator", - span: Span { - start: 262, - end: 272, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "compute:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "server", span: Span { - start: 273, - end: 281, + start: 330, + end: 336, }, }, - KeywordPart { - keyword: "with:", - span: Span { - start: 292, - end: 297, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "connect:", + span: Span { + start: 337, + end: 345, + }, }, - }, - ], - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 2, - ), - Span { - start: 282, - end: 283, + KeywordPart { + keyword: "port:", + span: Span { + start: 358, + end: 363, + }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 286, - end: 287, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 4, - ), - Span { - start: 290, - end: 291, - }, - ), - ], - is_cast: false, + KeywordPart { + keyword: "timeout:", span: Span { - start: 286, - end: 291, + start: 378, + end: 386, }, }, ], - is_cast: false, - span: Span { - start: 282, - end: 291, - }, - }, - MessageSend { - receiver: Literal( - Integer( - 10, + ), + arguments: [ + Literal( + String( + "localhost", ), Span { - start: 298, - end: 300, + start: 346, + end: 357, }, ), - selector: Binary( - "-", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 303, - end: 304, - }, - ), - selector: Binary( - "/", + MessageSend { + receiver: Literal( + Integer( + 8080, ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 307, - end: 308, - }, - ), - ], - is_cast: false, - span: Span { - start: 303, - end: 308, + Span { + start: 364, + end: 368, }, - }, - ], - is_cast: false, - span: Span { - start: 298, - end: 308, - }, - }, - ], - is_cast: false, - span: Span { - start: 262, - end: 308, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "server", - span: Span { - start: 330, - end: 336, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "connect:", - span: Span { - start: 337, - end: 345, - }, - }, - KeywordPart { - keyword: "port:", - span: Span { - start: 358, - end: 363, - }, - }, - KeywordPart { - keyword: "timeout:", - span: Span { - start: 378, - end: 386, - }, - }, - ], - ), - arguments: [ - Literal( - String( - "localhost", - ), - Span { - start: 346, - end: 357, - }, - ), - MessageSend { - receiver: Literal( - Integer( - 8080, ), - Span { + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "offset", + span: Span { + start: 371, + end: 377, + }, + }, + ), + ], + is_cast: false, + span: Span { start: 364, - end: 368, + end: 377, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + }, + MessageSend { + receiver: Identifier( Identifier { - name: "offset", + name: "maxTime", span: Span { - start: 371, - end: 377, + start: 387, + end: 394, }, }, ), - ], - is_cast: false, - span: Span { - start: 364, - end: 377, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "maxTime", - span: Span { - start: 387, - end: 394, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 397, - end: 398, - }, + selector: Binary( + "*", ), - ], - is_cast: false, - span: Span { - start: 387, - end: 398, + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 397, + end: 398, + }, + ), + ], + is_cast: false, + span: Span { + start: 387, + end: 398, + }, }, + ], + is_cast: false, + span: Span { + start: 330, + end: 398, }, - ], - is_cast: false, - span: Span { - start: 330, - end: 398, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "processor", - span: Span { - start: 431, - end: 440, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "transform:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "processor", span: Span { - start: 441, - end: 451, + start: 431, + end: 440, }, }, - KeywordPart { - keyword: "range:", - span: Span { - start: 470, - end: 476, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "transform:", + span: Span { + start: 441, + end: 451, + }, }, - }, - KeywordPart { - keyword: "to:", - span: Span { - start: 483, - end: 486, + KeywordPart { + keyword: "range:", + span: Span { + start: 470, + end: 476, + }, }, - }, - KeywordPart { - keyword: "step:", - span: Span { - start: 501, - end: 506, + KeywordPart { + keyword: "to:", + span: Span { + start: 483, + end: 486, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 454, - end: 455, - }, + KeywordPart { + keyword: "step:", + span: Span { + start: 501, + end: 506, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 454, + end: 455, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 458, + end: 459, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Identifier( + Identifier { + name: "factor", + span: Span { + start: 462, + end: 468, + }, + }, + ), + ], + is_cast: false, span: Span { start: 458, - end: 459, + end: 468, }, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Identifier( - Identifier { - name: "factor", - span: Span { - start: 462, - end: 468, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 458, - end: 468, }, + ], + span: Span { + start: 452, + end: 469, }, - ], - span: Span { - start: 452, - end: 469, - }, - }, - ), - Identifier( - Identifier { - name: "start", - span: Span { - start: 477, - end: 482, }, - }, - ), - MessageSend { - receiver: Identifier( + ), + Identifier( Identifier { name: "start", span: Span { - start: 487, - end: 492, + start: 477, + end: 482, }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + MessageSend { + receiver: Identifier( Identifier { - name: "count", + name: "start", span: Span { - start: 495, - end: 500, + start: 487, + end: 492, }, }, ), - ], - is_cast: false, - span: Span { - start: 487, - end: 500, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "increment", - span: Span { - start: 507, - end: 516, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "count", + span: Span { + start: 495, + end: 500, + }, + }, ), - Span { - start: 519, - end: 520, + ], + is_cast: false, + span: Span { + start: 487, + end: 500, + }, + }, + MessageSend { + receiver: Identifier( + Identifier { + name: "increment", + span: Span { + start: 507, + end: 516, + }, }, ), - ], - is_cast: false, - span: Span { - start: 507, - end: 520, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 519, + end: 520, + }, + ), + ], + is_cast: false, + span: Span { + start: 507, + end: 520, + }, }, + ], + is_cast: false, + span: Span { + start: 431, + end: 520, }, - ], - is_cast: false, - span: Span { - start: 431, - end: 520, }, }, ], @@ -565,7 +606,7 @@ Module { start: 189, end: 520, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__nested_blocks_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__nested_blocks_parser.snap index d4f122ee6..3b57ae8f7 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__nested_blocks_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__nested_blocks_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,526 +7,628 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "outerBlock", - span: Span { - start: 158, - end: 168, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "outerBlock", + span: Span { + start: 158, + end: 168, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 175, - end: 176, - }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [ + BlockParameter { name: "x", span: Span { - start: 179, - end: 180, + start: 175, + end: 176, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 183, - end: 184, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 179, + end: 180, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 183, + end: 184, + }, + ), + ], + is_cast: false, + span: Span { + start: 179, + end: 184, + }, + }, + }, ], - is_cast: false, span: Span { - start: 179, - end: 184, + start: 173, + end: 185, }, }, - ], - span: Span { - start: 173, - end: 185, - }, + ), }, - ), - ], - span: Span { - start: 172, - end: 186, + ], + span: Span { + start: 172, + end: 186, + }, }, + ), + span: Span { + start: 158, + end: 186, }, - ), - span: Span { - start: 158, - end: 186, }, }, - Assignment { - target: Identifier( - Identifier { - name: "innerBlock", - span: Span { - start: 187, - end: 197, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "outerBlock", + name: "innerBlock", span: Span { - start: 201, - end: 211, + start: 187, + end: 197, }, }, ), - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "outerBlock", + span: Span { + start: 201, + end: 211, + }, + }, + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 201, + end: 217, + }, + }, span: Span { - start: 201, + start: 187, end: 217, }, }, - span: Span { - start: 187, - end: 217, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 218, - end: 224, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "innerBlock", + name: "result", span: Span { - start: 228, - end: 238, + start: 218, + end: 224, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "innerBlock", span: Span { - start: 239, - end: 245, + start: 228, + end: 238, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 246, - end: 247, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 239, + end: 245, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 246, + end: 247, + }, + ), + ], + is_cast: false, + span: Span { + start: 228, + end: 247, + }, + }, span: Span { - start: 228, + start: 218, end: 247, }, }, - span: Span { - start: 218, - end: 247, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "deeplyNested", - span: Span { - start: 273, - end: 285, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "deeplyNested", + span: Span { + start: 273, + end: 285, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 292, - end: 294, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 292, + end: 294, + }, + ), + }, + ], + span: Span { + start: 291, + end: 295, + }, }, ), - ], - span: Span { - start: 291, - end: 295, }, + ], + span: Span { + start: 290, + end: 296, }, - ), - ], - span: Span { - start: 290, - end: 296, - }, + }, + ), }, - ), - ], - span: Span { - start: 289, - end: 297, + ], + span: Span { + start: 289, + end: 297, + }, }, + ), + span: Span { + start: 273, + end: 297, }, - ), - span: Span { - start: 273, - end: 297, }, }, - Assignment { - target: Identifier( - Identifier { - name: "blockWithNested", - span: Span { - start: 334, - end: 349, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "blockWithNested", + span: Span { + start: 334, + end: 349, + }, }, - }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 355, - end: 356, + ), + value: Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 355, + end: 356, + }, }, - }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "inner", - span: Span { - start: 364, - end: 369, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "y", + expression: Assignment { + target: Identifier( + Identifier { + name: "inner", span: Span { - start: 375, - end: 376, + start: 364, + end: 369, }, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { + ), + value: Block( + Block { + parameters: [ + BlockParameter { name: "y", span: Span { - start: 379, - end: 380, + start: 375, + end: 376, }, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 383, - end: 384, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "y", + span: Span { + start: 379, + end: 380, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 383, + end: 384, + }, + ), + ], + is_cast: false, + span: Span { + start: 379, + end: 384, + }, + }, + }, ], - is_cast: false, span: Span { - start: 379, - end: 384, + start: 373, + end: 385, }, }, - ], + ), span: Span { - start: 373, + start: 364, end: 385, }, }, - ), - span: Span { - start: 364, - end: 385, }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "inner", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "inner", + span: Span { + start: 390, + end: 395, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 396, + end: 402, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "x", + span: Span { + start: 403, + end: 404, + }, + }, + ), + ], + is_cast: false, span: Span { start: 390, - end: 395, + end: 404, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", - span: Span { - start: 396, - end: 402, - }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "x", - span: Span { - start: 403, - end: 404, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 390, - end: 404, }, + ], + span: Span { + start: 353, + end: 406, }, - ], - span: Span { - start: 353, - end: 406, }, + ), + span: Span { + start: 334, + end: 406, }, - ), - span: Span { - start: 334, - end: 406, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "processor", - span: Span { - start: 447, - end: 456, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "forEach:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "processor", span: Span { - start: 457, - end: 465, + start: 447, + end: 456, }, }, - KeywordPart { - keyword: "with:", - span: Span { - start: 472, - end: 477, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "forEach:", + span: Span { + start: 457, + end: 465, + }, }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "items", - span: Span { - start: 466, - end: 471, + KeywordPart { + keyword: "with:", + span: Span { + start: 472, + end: 477, + }, }, - }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "item", - span: Span { - start: 480, - end: 484, - }, + arguments: [ + Identifier( + Identifier { + name: "items", + span: Span { + start: 466, + end: 471, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "mapper", - span: Span { - start: 491, - end: 497, - }, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "item", + span: Span { + start: 480, + end: 484, }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "val", + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "mapper", span: Span { - start: 503, - end: 506, + start: 491, + end: 497, }, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { + ), + value: Block( + Block { + parameters: [ + BlockParameter { name: "val", span: Span { - start: 509, - end: 512, + start: 503, + end: 506, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 515, - end: 516, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 509, + end: 512, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 515, + end: 516, + }, + ), + ], + is_cast: false, + span: Span { + start: 509, + end: 516, + }, + }, + }, ], - is_cast: false, span: Span { - start: 509, - end: 516, + start: 501, + end: 517, }, }, - ], + ), span: Span { - start: 501, + start: 491, end: 517, }, }, - ), - span: Span { - start: 491, - end: 517, }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "mapper", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "mapper", + span: Span { + start: 522, + end: 528, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 529, + end: 535, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "item", + span: Span { + start: 536, + end: 540, + }, + }, + ), + ], + is_cast: false, span: Span { start: 522, - end: 528, + end: 540, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", - span: Span { - start: 529, - end: 535, - }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "item", - span: Span { - start: 536, - end: 540, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 522, - end: 540, }, + ], + span: Span { + start: 478, + end: 542, }, - ], - span: Span { - start: 478, - end: 542, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 447, - end: 542, + ), + ], + is_cast: false, + span: Span { + start: 447, + end: 542, + }, }, }, ], @@ -535,7 +636,7 @@ Module { start: 158, end: 542, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__nested_keyword_messages_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__nested_keyword_messages_parser.snap index 18e183c7d..33d63ab99 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__nested_keyword_messages_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__nested_keyword_messages_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,431 +7,455 @@ Module { classes: [], method_definitions: [], expressions: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "dict", - span: Span { - start: 196, - end: 200, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "dict", span: Span { - start: 201, - end: 204, + start: 196, + end: 200, }, }, - KeywordPart { - keyword: "put:", - span: Span { - start: 218, - end: 222, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 201, + end: 204, + }, }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "list", - span: Span { - start: 206, - end: 210, - }, + KeywordPart { + keyword: "put:", + span: Span { + start: 218, + end: 222, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "list", span: Span { - start: 211, - end: 214, + start: 206, + end: 210, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 215, - end: 216, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 211, + end: 214, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 215, + end: 216, + }, + ), + ], + is_cast: false, + span: Span { + start: 206, + end: 216, + }, + }, span: Span { - start: 206, - end: 216, + start: 205, + end: 217, }, }, - span: Span { - start: 205, - end: 217, - }, - }, - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "string", - span: Span { - start: 224, - end: 230, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "concat:", + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "string", span: Span { - start: 231, - end: 238, + start: 224, + end: 230, }, }, - ], - ), - arguments: [ - Literal( - String( - "value", - ), - Span { - start: 239, - end: 246, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "concat:", + span: Span { + start: 231, + end: 238, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "value", + ), + Span { + start: 239, + end: 246, + }, + ), + ], + is_cast: false, + span: Span { + start: 224, + end: 246, + }, + }, span: Span { - start: 224, - end: 246, + start: 223, + end: 247, }, }, - span: Span { - start: 223, - end: 247, - }, + ], + is_cast: false, + span: Span { + start: 196, + end: 247, }, - ], - is_cast: false, - span: Span { - start: 196, - end: 247, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "object", - span: Span { - start: 279, - end: 285, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "process:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "object", span: Span { - start: 286, - end: 294, + start: 279, + end: 285, }, }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "transformer", - span: Span { - start: 296, - end: 307, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "process:", + span: Span { + start: 286, + end: 294, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "apply:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "transformer", span: Span { - start: 308, - end: 314, + start: 296, + end: 307, }, }, - KeywordPart { - keyword: "with:", - span: Span { - start: 337, - end: 342, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "apply:", + span: Span { + start: 308, + end: 314, + }, }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "filter", - span: Span { - start: 316, - end: 322, - }, + KeywordPart { + keyword: "with:", + span: Span { + start: 337, + end: 342, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "check:", - span: Span { - start: 323, - end: 329, - }, - }, - ], - ), - arguments: [ - Identifier( + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( Identifier { - name: "value", + name: "filter", span: Span { - start: 330, - end: 335, + start: 316, + end: 322, }, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "check:", + span: Span { + start: 323, + end: 329, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "value", + span: Span { + start: 330, + end: 335, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 316, + end: 335, + }, + }, span: Span { - start: 316, - end: 335, + start: 315, + end: 336, }, }, + Identifier( + Identifier { + name: "options", + span: Span { + start: 343, + end: 350, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 296, + end: 350, + }, + }, + span: Span { + start: 295, + end: 351, + }, + }, + ], + is_cast: false, + span: Span { + start: 279, + end: 351, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "object", span: Span { - start: 315, - end: 336, + start: 385, + end: 391, }, }, - Identifier( - Identifier { - name: "options", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", span: Span { - start: 343, - end: 350, + start: 392, + end: 395, }, }, + ], + ), + arguments: [ + Literal( + String( + "key", + ), + Span { + start: 396, + end: 401, + }, ), ], is_cast: false, span: Span { - start: 296, - end: 350, + start: 385, + end: 401, }, }, span: Span { - start: 295, - end: 351, + start: 384, + end: 402, }, }, - ], - is_cast: false, - span: Span { - start: 279, - end: 351, - }, - }, - MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "object", + selector: Keyword( + [ + KeywordPart { + keyword: "update:", span: Span { - start: 385, - end: 391, + start: 403, + end: 410, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 392, - end: 395, - }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "newValue", + span: Span { + start: 411, + end: 419, }, - ], + }, ), - arguments: [ - Literal( - String( - "key", - ), - Span { - start: 396, - end: 401, - }, - ), - ], - is_cast: false, - span: Span { - start: 385, - end: 401, - }, - }, + ], + is_cast: false, span: Span { start: 384, - end: 402, + end: 419, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "update:", - span: Span { - start: 403, - end: 410, - }, - }, - ], - ), - arguments: [ - Identifier( + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "newValue", + name: "logger", span: Span { - start: 411, - end: 419, + start: 463, + end: 469, }, }, ), - ], - is_cast: false, - span: Span { - start: 384, - end: 419, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "logger", - span: Span { - start: 463, - end: 469, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "log:", - span: Span { - start: 470, - end: 474, - }, - }, - ], - ), - arguments: [ - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "formatter", - span: Span { - start: 476, - end: 485, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "log:", + span: Span { + start: 470, + end: 474, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "format:", + }, + ], + ), + arguments: [ + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "formatter", span: Span { - start: 486, - end: 493, + start: 476, + end: 485, }, }, - KeywordPart { - keyword: "with:", - span: Span { - start: 502, - end: 507, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "format:", + span: Span { + start: 486, + end: 493, + }, }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "message", - span: Span { - start: 494, - end: 501, + KeywordPart { + keyword: "with:", + span: Span { + start: 502, + end: 507, + }, }, - }, + ], ), - Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "timestamp", - span: Span { - start: 509, - end: 518, + arguments: [ + Identifier( + Identifier { + name: "message", + span: Span { + start: 494, + end: 501, + }, + }, + ), + Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "timestamp", + span: Span { + start: 509, + end: 518, + }, }, + ), + selector: Unary( + "now", + ), + arguments: [], + is_cast: false, + span: Span { + start: 509, + end: 522, }, - ), - selector: Unary( - "now", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 509, - end: 522, + start: 508, + end: 523, }, }, - span: Span { - start: 508, - end: 523, - }, + ], + is_cast: false, + span: Span { + start: 476, + end: 523, }, - ], - is_cast: false, + }, span: Span { - start: 476, - end: 523, + start: 475, + end: 524, }, }, - span: Span { - start: 475, - end: 524, - }, + ], + is_cast: false, + span: Span { + start: 463, + end: 524, }, - ], - is_cast: false, - span: Span { - start: 463, - end: 524, }, }, ], @@ -440,7 +463,7 @@ Module { start: 196, end: 524, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__sealed_class_violation_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__sealed_class_violation_parser.snap index d8065610e..56d77d963 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__sealed_class_violation_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__sealed_class_violation_parser.snap @@ -34,34 +34,40 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 216, - end: 220, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 223, - end: 224, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 216, + end: 220, + }, }, ), - ], - is_cast: false, - span: Span { - start: 216, - end: 224, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 223, + end: 224, + }, + ), + ], + is_cast: false, + span: Span { + start: 216, + end: 224, + }, }, }, ], @@ -98,7 +104,7 @@ Module { start: 179, end: 224, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__sealed_method_override_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__sealed_method_override_parser.snap index 5beb8f347..7089959b3 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__sealed_method_override_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__sealed_method_override_parser.snap @@ -34,15 +34,21 @@ Module { ), parameters: [], body: [ - Literal( - Integer( - 42, - ), - Span { - start: 246, - end: 248, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: Literal( + Integer( + 42, + ), + Span { + start: 246, + end: 248, + }, + ), + }, ], return_type: None, is_sealed: true, @@ -99,15 +105,21 @@ Module { ), parameters: [], body: [ - Literal( - Integer( - 99, - ), - Span { - start: 292, - end: 294, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: Literal( + Integer( + 99, + ), + Span { + start: 292, + end: 294, + }, + ), + }, ], return_type: None, is_sealed: false, @@ -164,15 +176,21 @@ Module { ), parameters: [], body: [ - Literal( - Integer( - 99, - ), - Span { - start: 331, - end: 333, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: Literal( + Integer( + 99, + ), + Span { + start: 331, + end: 333, + }, + ), + }, ], return_type: None, is_sealed: false, @@ -207,7 +225,7 @@ Module { start: 203, end: 333, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_dictionary_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_dictionary_parser.snap index 6818859c1..f13317186 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_dictionary_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_dictionary_parser.snap @@ -34,12 +34,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "size", - is_quoted: true, - span: Span { - start: 305, - end: 322, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "size", + is_quoted: true, + span: Span { + start: 305, + end: 322, + }, }, }, ], @@ -62,12 +68,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "keys", - is_quoted: true, - span: Span { - start: 333, - end: 350, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "keys", + is_quoted: true, + span: Span { + start: 333, + end: 350, + }, }, }, ], @@ -90,12 +102,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "values", - is_quoted: true, - span: Span { - start: 363, - end: 382, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "values", + is_quoted: true, + span: Span { + start: 363, + end: 382, + }, }, }, ], @@ -137,12 +155,18 @@ Module { }, ], body: [ - Primitive { - name: "at:", - is_quoted: true, - span: Span { - start: 396, - end: 412, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "at:", + is_quoted: true, + span: Span { + start: 396, + end: 412, + }, }, }, ], @@ -201,12 +225,18 @@ Module { }, ], body: [ - Primitive { - name: "at:ifAbsent:", - is_quoted: true, - span: Span { - start: 442, - end: 467, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "at:ifAbsent:", + is_quoted: true, + span: Span { + start: 442, + end: 467, + }, }, }, ], @@ -265,12 +295,18 @@ Module { }, ], body: [ - Primitive { - name: "at:put:", - is_quoted: true, - span: Span { - start: 492, - end: 512, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "at:put:", + is_quoted: true, + span: Span { + start: 492, + end: 512, + }, }, }, ], @@ -312,12 +348,18 @@ Module { }, ], body: [ - Primitive { - name: "includesKey:", - is_quoted: true, - span: Span { - start: 535, - end: 560, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "includesKey:", + is_quoted: true, + span: Span { + start: 535, + end: 560, + }, }, }, ], @@ -359,12 +401,18 @@ Module { }, ], body: [ - Primitive { - name: "removeKey:", - is_quoted: true, - span: Span { - start: 621, - end: 644, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "removeKey:", + is_quoted: true, + span: Span { + start: 621, + end: 644, + }, }, }, ], @@ -406,12 +454,18 @@ Module { }, ], body: [ - Primitive { - name: "merge:", - is_quoted: true, - span: Span { - start: 663, - end: 682, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "merge:", + is_quoted: true, + span: Span { + start: 663, + end: 682, + }, }, }, ], @@ -453,12 +507,18 @@ Module { }, ], body: [ - Primitive { - name: "keysAndValuesDo:", - is_quoted: true, - span: Span { - start: 727, - end: 756, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "keysAndValuesDo:", + is_quoted: true, + span: Span { + start: 727, + end: 756, + }, }, }, ], @@ -495,7 +555,7 @@ Module { start: 247, end: 756, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_list_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_list_parser.snap index 76e5b9365..1f2370b73 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_list_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_list_parser.snap @@ -34,12 +34,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "size", - is_quoted: true, - span: Span { - start: 259, - end: 276, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "size", + is_quoted: true, + span: Span { + start: 259, + end: 276, + }, }, }, ], @@ -62,12 +68,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "isEmpty", - is_quoted: true, - span: Span { - start: 290, - end: 310, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "isEmpty", + is_quoted: true, + span: Span { + start: 290, + end: 310, + }, }, }, ], @@ -90,12 +102,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "first", - is_quoted: true, - span: Span { - start: 322, - end: 340, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "first", + is_quoted: true, + span: Span { + start: 322, + end: 340, + }, }, }, ], @@ -118,12 +136,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "rest", - is_quoted: true, - span: Span { - start: 351, - end: 368, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "rest", + is_quoted: true, + span: Span { + start: 351, + end: 368, + }, }, }, ], @@ -146,12 +170,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "last", - is_quoted: true, - span: Span { - start: 379, - end: 396, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "last", + is_quoted: true, + span: Span { + start: 379, + end: 396, + }, }, }, ], @@ -193,12 +223,18 @@ Module { }, ], body: [ - Primitive { - name: "at:", - is_quoted: true, - span: Span { - start: 412, - end: 428, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "at:", + is_quoted: true, + span: Span { + start: 412, + end: 428, + }, }, }, ], @@ -240,12 +276,18 @@ Module { }, ], body: [ - Primitive { - name: "includes:", - is_quoted: true, - span: Span { - start: 449, - end: 471, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "includes:", + is_quoted: true, + span: Span { + start: 449, + end: 471, + }, }, }, ], @@ -268,12 +310,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "sort", - is_quoted: true, - span: Span { - start: 497, - end: 514, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "sort", + is_quoted: true, + span: Span { + start: 497, + end: 514, + }, }, }, ], @@ -315,12 +363,18 @@ Module { }, ], body: [ - Primitive { - name: "sort:", - is_quoted: true, - span: Span { - start: 537, - end: 555, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "sort:", + is_quoted: true, + span: Span { + start: 537, + end: 555, + }, }, }, ], @@ -343,12 +397,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "reversed", - is_quoted: true, - span: Span { - start: 570, - end: 591, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "reversed", + is_quoted: true, + span: Span { + start: 570, + end: 591, + }, }, }, ], @@ -371,12 +431,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "unique", - is_quoted: true, - span: Span { - start: 604, - end: 623, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "unique", + is_quoted: true, + span: Span { + start: 604, + end: 623, + }, }, }, ], @@ -418,12 +484,18 @@ Module { }, ], body: [ - Primitive { - name: "detect:", - is_quoted: true, - span: Span { - start: 656, - end: 676, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "detect:", + is_quoted: true, + span: Span { + start: 656, + end: 676, + }, }, }, ], @@ -482,12 +554,18 @@ Module { }, ], body: [ - Primitive { - name: "detect:ifNone:", - is_quoted: true, - span: Span { - start: 712, - end: 739, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "detect:ifNone:", + is_quoted: true, + span: Span { + start: 712, + end: 739, + }, }, }, ], @@ -529,12 +607,18 @@ Module { }, ], body: [ - Primitive { - name: "do:", - is_quoted: true, - span: Span { - start: 807, - end: 823, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "do:", + is_quoted: true, + span: Span { + start: 807, + end: 823, + }, }, }, ], @@ -576,12 +660,18 @@ Module { }, ], body: [ - Primitive { - name: "collect:", - is_quoted: true, - span: Span { - start: 844, - end: 865, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "collect:", + is_quoted: true, + span: Span { + start: 844, + end: 865, + }, }, }, ], @@ -623,12 +713,18 @@ Module { }, ], body: [ - Primitive { - name: "select:", - is_quoted: true, - span: Span { - start: 885, - end: 905, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "select:", + is_quoted: true, + span: Span { + start: 885, + end: 905, + }, }, }, ], @@ -670,12 +766,18 @@ Module { }, ], body: [ - Primitive { - name: "reject:", - is_quoted: true, - span: Span { - start: 925, - end: 945, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "reject:", + is_quoted: true, + span: Span { + start: 925, + end: 945, + }, }, }, ], @@ -734,12 +836,18 @@ Module { }, ], body: [ - Primitive { - name: "inject:into:", - is_quoted: true, - span: Span { - start: 979, - end: 1004, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "inject:into:", + is_quoted: true, + span: Span { + start: 979, + end: 1004, + }, }, }, ], @@ -781,12 +889,18 @@ Module { }, ], body: [ - Primitive { - name: "take:", - is_quoted: true, - span: Span { - start: 1035, - end: 1053, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "take:", + is_quoted: true, + span: Span { + start: 1035, + end: 1053, + }, }, }, ], @@ -828,12 +942,18 @@ Module { }, ], body: [ - Primitive { - name: "drop:", - is_quoted: true, - span: Span { - start: 1067, - end: 1085, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "drop:", + is_quoted: true, + span: Span { + start: 1067, + end: 1085, + }, }, }, ], @@ -856,12 +976,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "flatten", - is_quoted: true, - span: Span { - start: 1099, - end: 1119, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "flatten", + is_quoted: true, + span: Span { + start: 1099, + end: 1119, + }, }, }, ], @@ -903,12 +1029,18 @@ Module { }, ], body: [ - Primitive { - name: "flatMap:", - is_quoted: true, - span: Span { - start: 1140, - end: 1161, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "flatMap:", + is_quoted: true, + span: Span { + start: 1140, + end: 1161, + }, }, }, ], @@ -950,12 +1082,18 @@ Module { }, ], body: [ - Primitive { - name: "count:", - is_quoted: true, - span: Span { - start: 1180, - end: 1199, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "count:", + is_quoted: true, + span: Span { + start: 1180, + end: 1199, + }, }, }, ], @@ -997,12 +1135,18 @@ Module { }, ], body: [ - Primitive { - name: "anySatisfy:", - is_quoted: true, - span: Span { - start: 1223, - end: 1247, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "anySatisfy:", + is_quoted: true, + span: Span { + start: 1223, + end: 1247, + }, }, }, ], @@ -1044,12 +1188,18 @@ Module { }, ], body: [ - Primitive { - name: "allSatisfy:", - is_quoted: true, - span: Span { - start: 1271, - end: 1295, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "allSatisfy:", + is_quoted: true, + span: Span { + start: 1271, + end: 1295, + }, }, }, ], @@ -1083,12 +1233,18 @@ Module { }, ], body: [ - Primitive { - name: "++", - is_quoted: true, - span: Span { - start: 1330, - end: 1345, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "++", + is_quoted: true, + span: Span { + start: 1330, + end: 1345, + }, }, }, ], @@ -1147,12 +1303,18 @@ Module { }, ], body: [ - Primitive { - name: "from:to:", - is_quoted: true, - span: Span { - start: 1398, - end: 1419, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "from:to:", + is_quoted: true, + span: Span { + start: 1398, + end: 1419, + }, }, }, ], @@ -1194,216 +1356,252 @@ Module { }, ], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 1443, - end: 1447, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "inject:", - span: Span { - start: 1448, - end: 1455, - }, - }, - KeywordPart { - keyword: "into:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", span: Span { - start: 1458, - end: 1463, + start: 1443, + end: 1447, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 1456, - end: 1457, - }, ), - Block( - Block { - parameters: [ - BlockParameter { - name: "i", - span: Span { - start: 1466, - end: 1467, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "inject:", + span: Span { + start: 1448, + end: 1455, }, - BlockParameter { - name: "each", - span: Span { - start: 1469, - end: 1473, - }, + }, + KeywordPart { + keyword: "into:", + span: Span { + start: 1458, + end: 1463, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "newI", - span: Span { - start: 1482, - end: 1486, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "i", - span: Span { - start: 1490, - end: 1491, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 1494, - end: 1495, - }, - ), - ], - is_cast: false, + }, + ], + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 1456, + end: 1457, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "i", span: Span { - start: 1490, - end: 1495, + start: 1466, + end: 1467, }, }, - span: Span { - start: 1482, - end: 1495, + BlockParameter { + name: "each", + span: Span { + start: 1469, + end: 1473, + }, }, - }, - MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "each", - span: Span { - start: 1503, - end: 1507, - }, - }, - ), - selector: Binary( - "=:=", - ), - arguments: [ - Identifier( + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "item", + name: "newI", span: Span { - start: 1512, - end: 1516, + start: 1482, + end: 1486, }, }, ), - ], - is_cast: false, - span: Span { - start: 1503, - end: 1516, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "i", + span: Span { + start: 1490, + end: 1491, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1494, + end: 1495, + }, + ), + ], + is_cast: false, + span: Span { + start: 1490, + end: 1495, + }, + }, + span: Span { + start: 1482, + end: 1495, + }, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "each", + span: Span { + start: 1503, + end: 1507, + }, + }, + ), + selector: Binary( + "=:=", + ), + arguments: [ + Identifier( + Identifier { + name: "item", + span: Span { + start: 1512, + end: 1516, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 1517, - end: 1524, + start: 1503, + end: 1516, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Return { - value: Identifier( - Identifier { - name: "newI", - span: Span { - start: 1527, - end: 1531, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 1517, + end: 1524, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "newI", + span: Span { + start: 1527, + end: 1531, + }, + }, + ), + span: Span { + start: 1526, + end: 1531, + }, }, }, - ), + ], span: Span { - start: 1526, - end: 1531, + start: 1525, + end: 1532, }, }, - ], + ), + ], + is_cast: false, + span: Span { + start: 1503, + end: 1532, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "newI", span: Span { - start: 1525, - end: 1532, + start: 1540, + end: 1544, }, }, ), - ], - is_cast: false, - span: Span { - start: 1503, - end: 1532, }, + ], + span: Span { + start: 1464, + end: 1550, }, - Identifier( - Identifier { - name: "newI", - span: Span { - start: 1540, - end: 1544, - }, - }, - ), - ], - span: Span { - start: 1464, - end: 1550, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 1443, - end: 1550, - }, - }, - Identifier( - Identifier { - name: "nil", + ), + ], + is_cast: false, span: Span { - start: 1556, - end: 1559, + start: 1443, + end: 1550, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "nil", + span: Span { + start: 1556, + end: 1559, + }, + }, + ), + }, ], return_type: None, is_sealed: false, @@ -1443,194 +1641,224 @@ Module { }, ], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 1617, - end: 1621, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "inject:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "self", span: Span { - start: 1622, - end: 1629, + start: 1617, + end: 1621, }, }, - KeywordPart { - keyword: "into:", - span: Span { - start: 1632, - end: 1637, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "inject:", + span: Span { + start: 1622, + end: 1629, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 1630, - end: 1631, - }, + KeywordPart { + keyword: "into:", + span: Span { + start: 1632, + end: 1637, + }, + }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "i", - span: Span { - start: 1640, - end: 1641, + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 1630, + end: 1631, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "i", + span: Span { + start: 1640, + end: 1641, + }, }, - }, - BlockParameter { - name: "each", - span: Span { - start: 1643, - end: 1647, + BlockParameter { + name: "each", + span: Span { + start: 1643, + end: 1647, + }, }, - }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "newI", - span: Span { - start: 1656, - end: 1660, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "i", - span: Span { - start: 1664, - end: 1665, + expression: Assignment { + target: Identifier( + Identifier { + name: "newI", + span: Span { + start: 1656, + end: 1660, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "i", + span: Span { + start: 1664, + end: 1665, + }, + }, + ), + selector: Binary( + "+", ), - Span { - start: 1668, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1668, + end: 1669, + }, + ), + ], + is_cast: false, + span: Span { + start: 1664, end: 1669, }, - ), - ], - is_cast: false, - span: Span { - start: 1664, - end: 1669, + }, + span: Span { + start: 1656, + end: 1669, + }, }, }, - span: Span { - start: 1656, - end: 1669, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "block", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "block", + span: Span { + start: 1677, + end: 1682, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 1683, + end: 1689, + }, + }, + KeywordPart { + keyword: "value:", + span: Span { + start: 1695, + end: 1701, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "each", + span: Span { + start: 1690, + end: 1694, + }, + }, + ), + Identifier( + Identifier { + name: "newI", + span: Span { + start: 1702, + end: 1706, + }, + }, + ), + ], + is_cast: false, span: Span { start: 1677, - end: 1682, + end: 1706, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", - span: Span { - start: 1683, - end: 1689, - }, - }, - KeywordPart { - keyword: "value:", - span: Span { - start: 1695, - end: 1701, - }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "each", - span: Span { - start: 1690, - end: 1694, - }, - }, - ), - Identifier( + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( Identifier { name: "newI", span: Span { - start: 1702, - end: 1706, + start: 1714, + end: 1718, }, }, ), - ], - is_cast: false, - span: Span { - start: 1677, - end: 1706, }, + ], + span: Span { + start: 1638, + end: 1724, }, - Identifier( - Identifier { - name: "newI", - span: Span { - start: 1714, - end: 1718, - }, - }, - ), - ], - span: Span { - start: 1638, - end: 1724, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 1617, - end: 1724, - }, - }, - Identifier( - Identifier { - name: "nil", + ), + ], + is_cast: false, span: Span { - start: 1730, - end: 1733, + start: 1617, + end: 1724, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "nil", + span: Span { + start: 1730, + end: 1733, + }, + }, + ), + }, ], return_type: None, is_sealed: false, @@ -1670,12 +1898,18 @@ Module { }, ], body: [ - Primitive { - name: "zip:", - is_quoted: true, - span: Span { - start: 1765, - end: 1782, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "zip:", + is_quoted: true, + span: Span { + start: 1765, + end: 1782, + }, }, }, ], @@ -1717,12 +1951,18 @@ Module { }, ], body: [ - Primitive { - name: "groupBy:", - is_quoted: true, - span: Span { - start: 1803, - end: 1824, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "groupBy:", + is_quoted: true, + span: Span { + start: 1803, + end: 1824, + }, }, }, ], @@ -1764,12 +2004,18 @@ Module { }, ], body: [ - Primitive { - name: "partition:", - is_quoted: true, - span: Span { - start: 1847, - end: 1870, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "partition:", + is_quoted: true, + span: Span { + start: 1847, + end: 1870, + }, }, }, ], @@ -1811,12 +2057,18 @@ Module { }, ], body: [ - Primitive { - name: "takeWhile:", - is_quoted: true, - span: Span { - start: 1893, - end: 1916, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "takeWhile:", + is_quoted: true, + span: Span { + start: 1893, + end: 1916, + }, }, }, ], @@ -1858,12 +2110,18 @@ Module { }, ], body: [ - Primitive { - name: "dropWhile:", - is_quoted: true, - span: Span { - start: 1939, - end: 1962, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "dropWhile:", + is_quoted: true, + span: Span { + start: 1939, + end: 1962, + }, }, }, ], @@ -1905,12 +2163,18 @@ Module { }, ], body: [ - Primitive { - name: "intersperse:", - is_quoted: true, - span: Span { - start: 1991, - end: 2016, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "intersperse:", + is_quoted: true, + span: Span { + start: 1991, + end: 2016, + }, }, }, ], @@ -1952,12 +2216,18 @@ Module { }, ], body: [ - Primitive { - name: "add:", - is_quoted: true, - span: Span { - start: 2032, - end: 2049, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "add:", + is_quoted: true, + span: Span { + start: 2032, + end: 2049, + }, }, }, ], @@ -1994,7 +2264,7 @@ Module { start: 208, end: 2049, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_set_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_set_parser.snap index ea124ad03..98024491f 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_set_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_set_parser.snap @@ -64,12 +64,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "size", - is_quoted: true, - span: Span { - start: 294, - end: 311, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "size", + is_quoted: true, + span: Span { + start: 294, + end: 311, + }, }, }, ], @@ -92,12 +98,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "isEmpty", - is_quoted: true, - span: Span { - start: 325, - end: 345, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "isEmpty", + is_quoted: true, + span: Span { + start: 325, + end: 345, + }, }, }, ], @@ -139,12 +151,18 @@ Module { }, ], body: [ - Primitive { - name: "includes:", - is_quoted: true, - span: Span { - start: 386, - end: 408, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "includes:", + is_quoted: true, + span: Span { + start: 386, + end: 408, + }, }, }, ], @@ -186,12 +204,18 @@ Module { }, ], body: [ - Primitive { - name: "add:", - is_quoted: true, - span: Span { - start: 464, - end: 481, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "add:", + is_quoted: true, + span: Span { + start: 464, + end: 481, + }, }, }, ], @@ -233,12 +257,18 @@ Module { }, ], body: [ - Primitive { - name: "remove:", - is_quoted: true, - span: Span { - start: 503, - end: 523, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "remove:", + is_quoted: true, + span: Span { + start: 503, + end: 523, + }, }, }, ], @@ -280,12 +310,18 @@ Module { }, ], body: [ - Primitive { - name: "union:", - is_quoted: true, - span: Span { - start: 581, - end: 600, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "union:", + is_quoted: true, + span: Span { + start: 581, + end: 600, + }, }, }, ], @@ -327,12 +363,18 @@ Module { }, ], body: [ - Primitive { - name: "intersection:", - is_quoted: true, - span: Span { - start: 626, - end: 652, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "intersection:", + is_quoted: true, + span: Span { + start: 626, + end: 652, + }, }, }, ], @@ -374,12 +416,18 @@ Module { }, ], body: [ - Primitive { - name: "difference:", - is_quoted: true, - span: Span { - start: 676, - end: 700, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "difference:", + is_quoted: true, + span: Span { + start: 676, + end: 700, + }, }, }, ], @@ -421,12 +469,18 @@ Module { }, ], body: [ - Primitive { - name: "isSubsetOf:", - is_quoted: true, - span: Span { - start: 741, - end: 765, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "isSubsetOf:", + is_quoted: true, + span: Span { + start: 741, + end: 765, + }, }, }, ], @@ -449,12 +503,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "asList", - is_quoted: true, - span: Span { - start: 795, - end: 814, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "asList", + is_quoted: true, + span: Span { + start: 795, + end: 814, + }, }, }, ], @@ -496,12 +556,18 @@ Module { }, ], body: [ - Primitive { - name: "fromList:", - is_quoted: true, - span: Span { - start: 835, - end: 857, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "fromList:", + is_quoted: true, + span: Span { + start: 835, + end: 857, + }, }, }, ], @@ -543,12 +609,18 @@ Module { }, ], body: [ - Primitive { - name: "do:", - is_quoted: true, - span: Span { - start: 889, - end: 905, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "do:", + is_quoted: true, + span: Span { + start: 889, + end: 905, + }, }, }, ], @@ -585,7 +657,7 @@ Module { start: 221, end: 905, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_tuple_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_tuple_parser.snap index 69944a755..1ad74349f 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_tuple_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__stdlib_class_tuple_parser.snap @@ -34,12 +34,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "size", - is_quoted: true, - span: Span { - start: 302, - end: 319, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "size", + is_quoted: true, + span: Span { + start: 302, + end: 319, + }, }, }, ], @@ -81,12 +87,18 @@ Module { }, ], body: [ - Primitive { - name: "at:", - is_quoted: true, - span: Span { - start: 335, - end: 351, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "at:", + is_quoted: true, + span: Span { + start: 335, + end: 351, + }, }, }, ], @@ -109,12 +121,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "isOk", - is_quoted: true, - span: Span { - start: 409, - end: 426, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "isOk", + is_quoted: true, + span: Span { + start: 409, + end: 426, + }, }, }, ], @@ -137,12 +155,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "isError", - is_quoted: true, - span: Span { - start: 440, - end: 460, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "isError", + is_quoted: true, + span: Span { + start: 440, + end: 460, + }, }, }, ], @@ -165,12 +189,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "unwrap", - is_quoted: true, - span: Span { - start: 490, - end: 509, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "unwrap", + is_quoted: true, + span: Span { + start: 490, + end: 509, + }, }, }, ], @@ -212,12 +242,18 @@ Module { }, ], body: [ - Primitive { - name: "unwrapOr:", - is_quoted: true, - span: Span { - start: 533, - end: 555, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "unwrapOr:", + is_quoted: true, + span: Span { + start: 533, + end: 555, + }, }, }, ], @@ -259,12 +295,18 @@ Module { }, ], body: [ - Primitive { - name: "unwrapOrElse:", - is_quoted: true, - span: Span { - start: 581, - end: 607, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "unwrapOrElse:", + is_quoted: true, + span: Span { + start: 581, + end: 607, + }, }, }, ], @@ -287,12 +329,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "asString", - is_quoted: true, - span: Span { - start: 639, - end: 660, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "asString", + is_quoted: true, + span: Span { + start: 639, + end: 660, + }, }, }, ], @@ -329,7 +377,7 @@ Module { start: 240, end: 660, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__string_operations_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__string_operations_parser.snap index ce59dbeb2..48e5fcd2d 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__string_operations_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__string_operations_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,1015 +7,1159 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 177, - end: 185, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 177, + end: 185, + }, + }, + ), + value: Literal( + String( + "Hello", + ), + Span { + start: 189, + end: 196, }, - }, - ), - value: Literal( - String( - "Hello", ), - Span { - start: 189, + span: Span { + start: 177, end: 196, }, - ), - span: Span { - start: 177, - end: 196, }, }, - Assignment { - target: Identifier( - Identifier { - name: "name", - span: Span { - start: 197, - end: 201, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "name", + span: Span { + start: 197, + end: 201, + }, + }, + ), + value: Literal( + String( + "World", + ), + Span { + start: 205, + end: 212, }, - }, - ), - value: Literal( - String( - "World", ), - Span { - start: 205, + span: Span { + start: 197, end: 212, }, - ), - span: Span { - start: 197, - end: 212, }, }, - Assignment { - target: Identifier( - Identifier { - name: "message", - span: Span { - start: 213, - end: 220, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "message", + span: Span { + start: 213, + end: 220, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { + ), + value: MessageSend { receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 224, - end: 232, + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 224, + end: 232, + }, }, + ), + selector: Binary( + "++", + ), + arguments: [ + Literal( + String( + ", ", + ), + Span { + start: 236, + end: 240, + }, + ), + ], + is_cast: false, + span: Span { + start: 224, + end: 240, }, - ), + }, selector: Binary( "++", ), arguments: [ - Literal( - String( - ", ", - ), - Span { - start: 236, - end: 240, + Identifier( + Identifier { + name: "name", + span: Span { + start: 244, + end: 248, + }, }, ), ], is_cast: false, span: Span { start: 224, - end: 240, + end: 248, }, }, selector: Binary( "++", ), arguments: [ - Identifier( - Identifier { - name: "name", - span: Span { - start: 244, - end: 248, - }, + Literal( + String( + "!", + ), + Span { + start: 252, + end: 255, }, ), ], is_cast: false, span: Span { start: 224, - end: 248, + end: 255, }, }, - selector: Binary( - "++", - ), - arguments: [ - Literal( - String( - "!", - ), - Span { - start: 252, - end: 255, - }, - ), - ], - is_cast: false, span: Span { - start: 224, + start: 213, end: 255, }, }, - span: Span { - start: 213, - end: 255, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "len", - span: Span { - start: 286, - end: 289, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "greeting", + name: "len", span: Span { - start: 293, - end: 301, + start: 286, + end: 289, }, }, ), - selector: Unary( - "length", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 293, + end: 301, + }, + }, + ), + selector: Unary( + "length", + ), + arguments: [], + is_cast: false, + span: Span { + start: 293, + end: 308, + }, + }, span: Span { - start: 293, + start: 286, end: 308, }, }, - span: Span { - start: 286, - end: 308, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEqual", - span: Span { - start: 343, - end: 350, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 354, - end: 361, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEqual", + span: Span { + start: 343, + end: 350, + }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( "hello", ), Span { - start: 366, - end: 373, + start: 354, + end: 361, }, ), - ], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + String( + "hello", + ), + Span { + start: 366, + end: 373, + }, + ), + ], + is_cast: false, + span: Span { + start: 354, + end: 373, + }, + }, span: Span { - start: 354, + start: 343, end: 373, }, }, - span: Span { - start: 343, - end: 373, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "notEqual", - span: Span { - start: 374, - end: 382, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 386, - end: 393, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "notEqual", + span: Span { + start: 374, + end: 382, + }, }, ), - selector: Binary( - "/=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( - "world", + "hello", ), Span { - start: 397, - end: 404, + start: 386, + end: 393, }, ), - ], - is_cast: false, + selector: Binary( + "/=", + ), + arguments: [ + Literal( + String( + "world", + ), + Span { + start: 397, + end: 404, + }, + ), + ], + is_cast: false, + span: Span { + start: 386, + end: 404, + }, + }, span: Span { - start: 386, + start: 374, end: 404, }, }, - span: Span { - start: 374, - end: 404, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isLess", - span: Span { - start: 405, - end: 411, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "apple", - ), - Span { - start: 415, - end: 422, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isLess", + span: Span { + start: 405, + end: 411, + }, }, ), - selector: Binary( - "<", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( - "banana", + "apple", ), Span { - start: 425, - end: 433, + start: 415, + end: 422, }, ), - ], - is_cast: false, + selector: Binary( + "<", + ), + arguments: [ + Literal( + String( + "banana", + ), + Span { + start: 425, + end: 433, + }, + ), + ], + is_cast: false, + span: Span { + start: 415, + end: 433, + }, + }, span: Span { - start: 415, + start: 405, end: 433, }, }, - span: Span { - start: 405, - end: 433, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isGreater", - span: Span { - start: 434, - end: 443, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "zebra", - ), - Span { - start: 447, - end: 454, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isGreater", + span: Span { + start: 434, + end: 443, + }, }, ), - selector: Binary( - ">", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( - "apple", + "zebra", ), Span { - start: 457, - end: 464, + start: 447, + end: 454, }, ), - ], - is_cast: false, + selector: Binary( + ">", + ), + arguments: [ + Literal( + String( + "apple", + ), + Span { + start: 457, + end: 464, + }, + ), + ], + is_cast: false, + span: Span { + start: 447, + end: 464, + }, + }, span: Span { - start: 447, + start: 434, end: 464, }, }, - span: Span { - start: 434, - end: 464, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "upper", - span: Span { - start: 508, - end: 513, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "greeting", + name: "upper", span: Span { - start: 517, - end: 525, + start: 508, + end: 513, }, }, ), - selector: Unary( - "uppercase", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 517, + end: 525, + }, + }, + ), + selector: Unary( + "uppercase", + ), + arguments: [], + is_cast: false, + span: Span { + start: 517, + end: 535, + }, + }, span: Span { - start: 517, + start: 508, end: 535, }, }, - span: Span { - start: 508, - end: 535, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "lower", - span: Span { - start: 536, - end: 541, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "upper", + name: "lower", span: Span { - start: 545, - end: 550, + start: 536, + end: 541, }, }, ), - selector: Unary( - "lowercase", - ), - arguments: [], - is_cast: false, - span: Span { - start: 545, - end: 560, - }, - }, - span: Span { - start: 536, - end: 560, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "padded", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "upper", + span: Span { + start: 545, + end: 550, + }, + }, + ), + selector: Unary( + "lowercase", + ), + arguments: [], + is_cast: false, span: Span { - start: 593, - end: 599, + start: 545, + end: 560, }, }, - ), - value: Literal( - String( - " hello ", - ), - Span { - start: 603, - end: 614, + span: Span { + start: 536, + end: 560, }, - ), - span: Span { - start: 593, - end: 614, }, }, - Assignment { - target: Identifier( - Identifier { - name: "trimmed", - span: Span { - start: 615, - end: 622, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { name: "padded", span: Span { - start: 626, - end: 632, + start: 593, + end: 599, }, }, ), - selector: Unary( - "trim", + value: Literal( + String( + " hello ", + ), + Span { + start: 603, + end: 614, + }, ), - arguments: [], - is_cast: false, span: Span { - start: 626, - end: 637, + start: 593, + end: 614, }, }, - span: Span { - start: 615, - end: 637, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "empty", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "trimmed", + span: Span { + start: 615, + end: 622, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "padded", + span: Span { + start: 626, + end: 632, + }, + }, + ), + selector: Unary( + "trim", + ), + arguments: [], + is_cast: false, span: Span { - start: 684, - end: 689, + start: 626, + end: 637, }, }, - ), - value: Literal( - String( - "", - ), - Span { - start: 693, - end: 695, + span: Span { + start: 615, + end: 637, }, - ), - span: Span { - start: 684, - end: 695, }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEmpty", - span: Span { - start: 696, - end: 703, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { name: "empty", span: Span { - start: 707, - end: 712, + start: 684, + end: 689, }, }, ), - selector: Unary( - "isEmpty", - ), - arguments: [], - is_cast: false, - span: Span { - start: 707, - end: 720, + value: Literal( + String( + "", + ), + Span { + start: 693, + end: 695, + }, + ), + span: Span { + start: 684, + end: 695, }, }, - span: Span { - start: 696, - end: 720, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isNotEmpty", - span: Span { - start: 721, - end: 731, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "isEmpty", span: Span { - start: 735, - end: 742, + start: 696, + end: 703, }, }, ), - selector: Unary( - "isNotEmpty", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "empty", + span: Span { + start: 707, + end: 712, + }, + }, + ), + selector: Unary( + "isEmpty", + ), + arguments: [], + is_cast: false, + span: Span { + start: 707, + end: 720, + }, + }, span: Span { - start: 735, - end: 753, + start: 696, + end: 720, }, }, - span: Span { - start: 721, - end: 753, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "firstChar", - span: Span { - start: 813, - end: 822, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 826, - end: 833, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isNotEmpty", + span: Span { + start: 721, + end: 731, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 834, - end: 837, + start: 735, + end: 742, }, }, - ], + ), + selector: Unary( + "isNotEmpty", + ), + arguments: [], + is_cast: false, + span: Span { + start: 735, + end: 753, + }, + }, + span: Span { + start: 721, + end: 753, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "firstChar", + span: Span { + start: 813, + end: 822, + }, + }, ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: Literal( + String( + "hello", ), Span { - start: 838, - end: 839, + start: 826, + end: 833, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 834, + end: 837, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 838, + end: 839, + }, + ), + ], + is_cast: false, + span: Span { + start: 826, + end: 839, + }, + }, span: Span { - start: 826, + start: 813, end: 839, }, }, - span: Span { - start: 813, - end: 839, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "thirdChar", - span: Span { - start: 840, - end: 849, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 853, - end: 860, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", - span: Span { - start: 861, - end: 864, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "thirdChar", + span: Span { + start: 840, + end: 849, }, - ], + }, ), - arguments: [ - Literal( - Integer( - 3, + value: MessageSend { + receiver: Literal( + String( + "hello", ), Span { - start: 865, - end: 866, + start: 853, + end: 860, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 861, + end: 864, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 865, + end: 866, + }, + ), + ], + is_cast: false, + span: Span { + start: 853, + end: 866, + }, + }, span: Span { - start: 853, + start: 840, end: 866, }, }, - span: Span { - start: 840, - end: 866, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "found", - span: Span { - start: 908, - end: 913, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "found", span: Span { - start: 917, - end: 924, + start: 908, + end: 913, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "includesSubstring:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 925, - end: 943, + start: 917, + end: 924, }, }, - ], - ), - arguments: [ - Literal( - String( - "World", - ), - Span { - start: 944, - end: 951, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "includesSubstring:", + span: Span { + start: 925, + end: 943, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "World", + ), + Span { + start: 944, + end: 951, + }, + ), + ], + is_cast: false, + span: Span { + start: 917, + end: 951, + }, + }, span: Span { - start: 917, + start: 908, end: 951, }, }, - span: Span { - start: 908, - end: 951, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "notFound", - span: Span { - start: 952, - end: 960, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "notFound", span: Span { - start: 964, - end: 971, + start: 952, + end: 960, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "includesSubstring:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 972, - end: 990, + start: 964, + end: 971, }, }, - ], - ), - arguments: [ - Literal( - String( - "xyz", - ), - Span { - start: 991, - end: 996, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "includesSubstring:", + span: Span { + start: 972, + end: 990, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "xyz", + ), + Span { + start: 991, + end: 996, + }, + ), + ], + is_cast: false, + span: Span { + start: 964, + end: 996, + }, + }, span: Span { - start: 964, + start: 952, end: 996, }, }, - span: Span { - start: 952, - end: 996, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "starts", - span: Span { - start: 1041, - end: 1047, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "starts", span: Span { - start: 1051, - end: 1058, + start: 1041, + end: 1047, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "startsWith:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 1059, - end: 1070, + start: 1051, + end: 1058, }, }, - ], - ), - arguments: [ - Literal( - String( - "Hello", - ), - Span { - start: 1071, - end: 1078, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "startsWith:", + span: Span { + start: 1059, + end: 1070, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "Hello", + ), + Span { + start: 1071, + end: 1078, + }, + ), + ], + is_cast: false, + span: Span { + start: 1051, + end: 1078, + }, + }, span: Span { - start: 1051, + start: 1041, end: 1078, }, }, - span: Span { - start: 1041, - end: 1078, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "ends", - span: Span { - start: 1079, - end: 1083, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "ends", span: Span { - start: 1087, - end: 1094, + start: 1079, + end: 1083, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "endsWith:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 1095, - end: 1104, + start: 1087, + end: 1094, }, }, - ], - ), - arguments: [ - Literal( - String( - "!", - ), - Span { - start: 1105, - end: 1108, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "endsWith:", + span: Span { + start: 1095, + end: 1104, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "!", + ), + Span { + start: 1105, + end: 1108, + }, + ), + ], + is_cast: false, + span: Span { + start: 1087, + end: 1108, + }, + }, span: Span { - start: 1087, + start: 1079, end: 1108, }, }, - span: Span { - start: 1079, - end: 1108, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "csv", - span: Span { - start: 1142, - end: 1145, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "csv", + span: Span { + start: 1142, + end: 1145, + }, }, - }, - ), - value: Literal( - String( - "a,b,c,d", ), - Span { - start: 1149, + value: Literal( + String( + "a,b,c,d", + ), + Span { + start: 1149, + end: 1158, + }, + ), + span: Span { + start: 1142, end: 1158, }, - ), - span: Span { - start: 1142, - end: 1158, }, }, - Assignment { - target: Identifier( - Identifier { - name: "parts", - span: Span { - start: 1159, - end: 1164, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "csv", + name: "parts", span: Span { - start: 1168, - end: 1171, + start: 1159, + end: 1164, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "split:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "csv", span: Span { - start: 1172, - end: 1178, + start: 1168, + end: 1171, }, }, - ], - ), - arguments: [ - Literal( - String( - ",", - ), - Span { - start: 1179, - end: 1182, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "split:", + span: Span { + start: 1172, + end: 1178, + }, + }, + ], + ), + arguments: [ + Literal( + String( + ",", + ), + Span { + start: 1179, + end: 1182, + }, + ), + ], + is_cast: false, + span: Span { + start: 1168, + end: 1182, + }, + }, span: Span { - start: 1168, + start: 1159, end: 1182, }, }, - span: Span { - start: 1159, - end: 1182, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "reversed", - span: Span { - start: 1214, - end: 1222, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "reversed", + span: Span { + start: 1214, + end: 1222, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", + ), + value: MessageSend { + receiver: Literal( + String( + "hello", + ), + Span { + start: 1226, + end: 1233, + }, ), - Span { + selector: Unary( + "reverse", + ), + arguments: [], + is_cast: false, + span: Span { start: 1226, - end: 1233, + end: 1241, }, - ), - selector: Unary( - "reverse", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 1226, + start: 1214, end: 1241, }, }, - span: Span { - start: 1214, - end: 1241, - }, }, ], span: Span { start: 177, end: 1241, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__typed_class_warnings_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__typed_class_warnings_parser.snap index d85e355d7..e58ef1daa 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__typed_class_warnings_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__typed_class_warnings_parser.snap @@ -75,27 +75,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 409, + end: 413, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 409, - end: 413, + start: 414, + end: 419, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 414, + start: 409, end: 419, }, }, - span: Span { - start: 409, - end: 419, - }, }, ], return_type: Some( @@ -127,98 +133,110 @@ Module { ), parameters: [], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 497, - end: 501, - }, - }, - ), - field: Identifier { - name: "value", - span: Span { - start: 502, - end: 507, - }, - }, - span: Span { - start: 497, - end: 507, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 511, - end: 515, + start: 497, + end: 501, }, }, ), field: Identifier { name: "value", span: Span { - start: 516, - end: 521, + start: 502, + end: 507, }, }, span: Span { - start: 511, - end: 521, + start: 497, + end: 507, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 511, + end: 515, + }, + }, ), - Span { - start: 524, - end: 525, + field: Identifier { + name: "value", + span: Span { + start: 516, + end: 521, + }, + }, + span: Span { + start: 511, + end: 521, }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 524, + end: 525, + }, + ), + ], + is_cast: false, + span: Span { + start: 511, + end: 525, + }, + }, span: Span { - start: 511, + start: 497, end: 525, }, }, - span: Span { - start: 497, - end: 525, - }, }, - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 531, + end: 535, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 531, - end: 535, + start: 536, + end: 541, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 536, + start: 531, end: 541, }, }, - span: Span { - start: 531, - end: 541, - }, }, ], return_type: None, @@ -259,98 +277,110 @@ Module { }, ], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 635, - end: 639, - }, - }, - ), - field: Identifier { - name: "value", - span: Span { - start: 640, - end: 645, - }, - }, - span: Span { - start: 635, - end: 645, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 649, - end: 653, + start: 635, + end: 639, }, }, ), field: Identifier { name: "value", span: Span { - start: 654, - end: 659, + start: 640, + end: 645, }, }, span: Span { - start: 649, - end: 659, + start: 635, + end: 645, }, }, - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "amount", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 649, + end: 653, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 662, - end: 668, + start: 654, + end: 659, }, }, + span: Span { + start: 649, + end: 659, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Identifier( + Identifier { + name: "amount", + span: Span { + start: 662, + end: 668, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 649, + end: 668, + }, + }, span: Span { - start: 649, + start: 635, end: 668, }, }, - span: Span { - start: 635, - end: 668, - }, }, - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 674, + end: 678, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 674, - end: 678, + start: 679, + end: 684, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 679, + start: 674, end: 684, }, }, - span: Span { - start: 674, - end: 684, - }, }, ], return_type: Some( @@ -396,7 +426,7 @@ Module { start: 275, end: 684, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__typed_methods_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__typed_methods_parser.snap index f6d9b2860..f223be098 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__typed_methods_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__typed_methods_parser.snap @@ -75,27 +75,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 166, + end: 170, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 166, - end: 170, + start: 171, + end: 176, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 171, + start: 166, end: 176, }, }, - span: Span { - start: 166, - end: 176, - }, }, ], return_type: Some( @@ -156,76 +162,82 @@ Module { }, ], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 280, - end: 284, - }, - }, - ), - field: Identifier { - name: "value", - span: Span { - start: 285, - end: 290, - }, - }, - span: Span { - start: 280, - end: 290, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 294, - end: 298, + start: 280, + end: 284, }, }, ), field: Identifier { name: "value", span: Span { - start: 299, - end: 304, + start: 285, + end: 290, }, }, span: Span { - start: 294, - end: 304, + start: 280, + end: 290, }, }, - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "amount", + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 294, + end: 298, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 307, - end: 313, + start: 299, + end: 304, }, }, + span: Span { + start: 294, + end: 304, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Identifier( + Identifier { + name: "amount", + span: Span { + start: 307, + end: 313, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 294, + end: 313, + }, + }, span: Span { - start: 294, + start: 280, end: 313, }, }, - span: Span { - start: 280, - end: 313, - }, }, ], return_type: Some( @@ -257,133 +269,151 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 384, + end: 388, + }, + }, + ), + field: Identifier { + name: "value", span: Span { - start: 384, - end: 388, + start: 389, + end: 394, }, }, - ), - field: Identifier { - name: "value", span: Span { - start: 389, + start: 384, end: 394, }, }, + selector: Binary( + ">", + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 397, + end: 398, + }, + ), + ], + is_cast: false, span: Span { start: 384, - end: 394, + end: 398, }, }, - selector: Binary( - ">", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 397, - end: 398, - }, - ), - ], - is_cast: false, span: Span { - start: 384, - end: 398, + start: 383, + end: 399, }, }, - span: Span { - start: 383, - end: 399, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 400, - end: 407, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 400, + end: 407, + }, }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 421, - end: 429, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 421, + end: 429, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 409, + end: 413, + }, + }, + ), + field: Identifier { + name: "value", + span: Span { + start: 414, + end: 419, + }, + }, span: Span { start: 409, - end: 413, + end: 419, }, }, - ), - field: Identifier { - name: "value", - span: Span { - start: 414, - end: 419, - }, - }, - span: Span { - start: 409, - end: 419, }, + ], + span: Span { + start: 408, + end: 420, }, - ], - span: Span { - start: 408, - end: 420, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "nil", - span: Span { - start: 431, - end: 434, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "nil", + span: Span { + start: 431, + end: 434, + }, + }, + ), }, - ), - ], - span: Span { - start: 430, - end: 435, + ], + span: Span { + start: 430, + end: 435, + }, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 383, - end: 435, + ), + ], + is_cast: false, + span: Span { + start: 383, + end: 435, + }, }, }, ], @@ -433,76 +463,82 @@ Module { ), parameters: [], body: [ - Assignment { - target: FieldAccess { - receiver: Identifier( - Identifier { - name: "self", - span: Span { - start: 503, - end: 507, - }, - }, - ), - field: Identifier { - name: "value", - span: Span { - start: 508, - end: 513, - }, - }, - span: Span { - start: 503, - end: 513, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - value: MessageSend { - receiver: FieldAccess { + expression: Assignment { + target: FieldAccess { receiver: Identifier( Identifier { name: "self", span: Span { - start: 517, - end: 521, + start: 503, + end: 507, }, }, ), field: Identifier { name: "value", span: Span { - start: 522, - end: 527, + start: 508, + end: 513, }, }, span: Span { - start: 517, - end: 527, + start: 503, + end: 513, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + value: MessageSend { + receiver: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 517, + end: 521, + }, + }, ), - Span { - start: 530, - end: 531, + field: Identifier { + name: "value", + span: Span { + start: 522, + end: 527, + }, + }, + span: Span { + start: 517, + end: 527, }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 530, + end: 531, + }, + ), + ], + is_cast: false, + span: Span { + start: 517, + end: 531, + }, + }, span: Span { - start: 517, + start: 503, end: 531, }, }, - span: Span { - start: 503, - end: 531, - }, }, ], return_type: None, @@ -538,7 +574,7 @@ Module { start: 48, end: 531, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Typed method definitions for spec generation", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__typed_value_type_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__typed_value_type_parser.snap index 87377bf61..e117537e6 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__typed_value_type_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__typed_value_type_parser.snap @@ -115,27 +115,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 171, + end: 175, + }, + }, + ), + field: Identifier { + name: "x", span: Span { - start: 171, - end: 175, + start: 176, + end: 177, }, }, - ), - field: Identifier { - name: "x", span: Span { - start: 176, + start: 171, end: 177, }, }, - span: Span { - start: 171, - end: 177, - }, }, ], return_type: Some( @@ -167,27 +173,33 @@ Module { ), parameters: [], body: [ - FieldAccess { - receiver: Identifier( - Identifier { - name: "self", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: FieldAccess { + receiver: Identifier( + Identifier { + name: "self", + span: Span { + start: 199, + end: 203, + }, + }, + ), + field: Identifier { + name: "y", span: Span { - start: 199, - end: 203, + start: 204, + end: 205, }, }, - ), - field: Identifier { - name: "y", span: Span { - start: 204, + start: 199, end: 205, }, }, - span: Span { - start: 199, - end: 205, - }, }, ], return_type: Some( @@ -248,12 +260,18 @@ Module { }, ], body: [ - Primitive { - name: "distanceTo:", - is_quoted: true, - span: Span { - start: 281, - end: 305, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "distanceTo:", + is_quoted: true, + span: Span { + start: 281, + end: 305, + }, }, }, ], @@ -286,12 +304,18 @@ Module { ), parameters: [], body: [ - Primitive { - name: "printString", - is_quoted: true, - span: Span { - start: 354, - end: 378, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Primitive { + name: "printString", + is_quoted: true, + span: Span { + start: 354, + end: 378, + }, }, }, ], @@ -328,7 +352,7 @@ Module { start: 48, end: 378, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Typed value type methods for spec generation", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__unary_operators_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__unary_operators_parser.snap index 09907a71a..628a1d85c 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__unary_operators_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__unary_operators_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,522 +7,612 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "negatedNum", - span: Span { - start: 268, - end: 278, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "negatedNum", + span: Span { + start: 268, + end: 278, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, + ), + value: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 282, + end: 283, + }, ), - Span { + selector: Unary( + "negated", + ), + arguments: [], + is_cast: false, + span: Span { start: 282, - end: 283, + end: 291, }, - ), - selector: Unary( - "negated", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 282, + start: 268, end: 291, }, }, - span: Span { - start: 268, - end: 291, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "absValue", - span: Span { - start: 356, - end: 364, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "absValue", + span: Span { + start: 356, + end: 364, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: Literal( - Integer( - -10, + ), + value: MessageSend { + receiver: Parenthesized { + expression: Literal( + Integer( + -10, + ), + Span { + start: 369, + end: 372, + }, ), - Span { - start: 369, - end: 372, + span: Span { + start: 368, + end: 373, }, + }, + selector: Unary( + "abs", ), + arguments: [], + is_cast: false, span: Span { start: 368, - end: 373, + end: 377, }, }, - selector: Unary( - "abs", - ), - arguments: [], - is_cast: false, span: Span { - start: 368, + start: 356, end: 377, }, }, - span: Span { - start: 356, - end: 377, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isZero1", - span: Span { - start: 436, - end: 443, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isZero1", + span: Span { + start: 436, + end: 443, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 0, + ), + value: MessageSend { + receiver: Literal( + Integer( + 0, + ), + Span { + start: 447, + end: 448, + }, ), - Span { + selector: Unary( + "isZero", + ), + arguments: [], + is_cast: false, + span: Span { start: 447, - end: 448, + end: 455, }, - ), - selector: Unary( - "isZero", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 447, + start: 436, end: 455, }, }, - span: Span { - start: 436, - end: 455, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isZero2", - span: Span { - start: 456, - end: 463, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isZero2", + span: Span { + start: 456, + end: 463, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, + ), + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 467, + end: 469, + }, ), - Span { + selector: Unary( + "isZero", + ), + arguments: [], + is_cast: false, + span: Span { start: 467, - end: 469, + end: 476, }, - ), - selector: Unary( - "isZero", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 467, + start: 456, end: 476, }, }, - span: Span { - start: 456, - end: 476, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "evenCheck", - span: Span { - start: 496, - end: 505, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "evenCheck", + span: Span { + start: 496, + end: 505, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 4, + ), + value: MessageSend { + receiver: Literal( + Integer( + 4, + ), + Span { + start: 509, + end: 510, + }, ), - Span { + selector: Unary( + "isEven", + ), + arguments: [], + is_cast: false, + span: Span { start: 509, - end: 510, + end: 517, }, - ), - selector: Unary( - "isEven", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 509, + start: 496, end: 517, }, }, - span: Span { - start: 496, - end: 517, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "oddCheck", - span: Span { - start: 518, - end: 526, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "oddCheck", + span: Span { + start: 518, + end: 526, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 7, + ), + value: MessageSend { + receiver: Literal( + Integer( + 7, + ), + Span { + start: 530, + end: 531, + }, ), - Span { + selector: Unary( + "isOdd", + ), + arguments: [], + is_cast: false, + span: Span { start: 530, - end: 531, + end: 537, }, - ), - selector: Unary( - "isOdd", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 530, + start: 518, end: 537, }, }, - span: Span { - start: 518, - end: 537, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "notTrue", - span: Span { - start: 594, - end: 601, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "notTrue", span: Span { - start: 605, - end: 609, + start: 594, + end: 601, }, }, ), - selector: Unary( - "not", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", + span: Span { + start: 605, + end: 609, + }, + }, + ), + selector: Unary( + "not", + ), + arguments: [], + is_cast: false, + span: Span { + start: 605, + end: 613, + }, + }, span: Span { - start: 605, + start: 594, end: 613, }, }, - span: Span { - start: 594, - end: 613, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "notFalse", - span: Span { - start: 614, - end: 622, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "notFalse", span: Span { - start: 626, - end: 631, + start: 614, + end: 622, }, }, ), - selector: Unary( - "not", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", + span: Span { + start: 626, + end: 631, + }, + }, + ), + selector: Unary( + "not", + ), + arguments: [], + is_cast: false, + span: Span { + start: 626, + end: 635, + }, + }, span: Span { - start: 626, + start: 614, end: 635, }, }, - span: Span { - start: 614, - end: 635, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "chained", - span: Span { - start: 704, - end: 711, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "chained", + span: Span { + start: 704, + end: 711, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Literal( - Integer( - 5, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 715, + end: 716, + }, ), - Span { + selector: Unary( + "negated", + ), + arguments: [], + is_cast: false, + span: Span { start: 715, - end: 716, + end: 724, }, - ), + }, selector: Unary( - "negated", + "abs", ), arguments: [], is_cast: false, span: Span { start: 715, - end: 724, + end: 728, }, }, - selector: Unary( - "abs", - ), - arguments: [], - is_cast: false, span: Span { - start: 715, + start: 704, end: 728, }, }, - span: Span { - start: 704, - end: 728, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 776, - end: 783, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 776, + end: 783, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 787, + end: 788, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 787, + span: Span { + start: 776, end: 788, }, - ), - span: Span { - start: 776, - end: 788, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 789, - end: 795, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 789, + end: 795, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 800, - end: 807, + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 800, + end: 807, + }, }, + ), + selector: Unary( + "isZero", + ), + arguments: [], + is_cast: false, + span: Span { + start: 800, + end: 814, }, - ), - selector: Unary( - "isZero", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 800, - end: 814, + start: 799, + end: 815, }, }, - span: Span { - start: 799, - end: 815, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 816, - end: 823, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 816, + end: 823, + }, }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 828, - end: 836, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 828, + end: 836, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 825, - end: 826, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 0, + ), + Span { + start: 825, + end: 826, + }, + ), }, - ), - ], - span: Span { - start: 824, - end: 827, + ], + span: Span { + start: 824, + end: 827, + }, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "counter", - span: Span { - start: 838, - end: 845, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "counter", + span: Span { + start: 838, + end: 845, + }, + }, + ), }, - ), - ], - span: Span { - start: 837, - end: 846, + ], + span: Span { + start: 837, + end: 846, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 799, + end: 846, + }, + }, span: Span { - start: 799, + start: 789, end: 846, }, }, - span: Span { - start: 789, - end: 846, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "blockUnary", - span: Span { - start: 878, - end: 888, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "blockUnary", + span: Span { + start: 878, + end: 888, + }, }, - }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 894, - end: 895, + ), + value: Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 894, + end: 895, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 898, + end: 899, + }, + }, + ), + selector: Unary( + "negated", + ), + arguments: [], + is_cast: false, span: Span { start: 898, - end: 899, + end: 907, }, }, - ), - selector: Unary( - "negated", - ), - arguments: [], - is_cast: false, - span: Span { - start: 898, - end: 907, }, + ], + span: Span { + start: 892, + end: 908, }, - ], - span: Span { - start: 892, - end: 908, }, + ), + span: Span { + start: 878, + end: 908, }, - ), - span: Span { - start: 878, - end: 908, }, }, ], @@ -531,7 +620,7 @@ Module { start: 268, end: 908, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__unicode_string_literals_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__unicode_string_literals_parser.snap index 79521f543..02f175e21 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__unicode_string_literals_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__unicode_string_literals_parser.snap @@ -7,100 +7,124 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "cafe", - span: Span { - start: 180, - end: 184, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "cafe", + span: Span { + start: 180, + end: 184, + }, + }, + ), + value: Literal( + String( + "café", + ), + Span { + start: 188, + end: 195, }, - }, - ), - value: Literal( - String( - "café", ), - Span { - start: 188, + span: Span { + start: 180, end: 195, }, - ), - span: Span { - start: 180, - end: 195, }, }, - Assignment { - target: Identifier( - Identifier { - name: "japanese", - span: Span { - start: 196, - end: 204, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "japanese", + span: Span { + start: 196, + end: 204, + }, }, - }, - ), - value: Literal( - String( - "日本語", ), - Span { - start: 208, + value: Literal( + String( + "日本語", + ), + Span { + start: 208, + end: 219, + }, + ), + span: Span { + start: 196, end: 219, }, - ), - span: Span { - start: 196, - end: 219, }, }, - Assignment { - target: Identifier( - Identifier { - name: "emoji", - span: Span { - start: 220, - end: 225, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "emoji", + span: Span { + start: 220, + end: 225, + }, }, - }, - ), - value: Literal( - String( - "🎉", ), - Span { - start: 229, + value: Literal( + String( + "🎉", + ), + Span { + start: 229, + end: 235, + }, + ), + span: Span { + start: 220, end: 235, }, - ), - span: Span { - start: 220, - end: 235, }, }, - Assignment { - target: Identifier( - Identifier { - name: "mixed", - span: Span { - start: 278, - end: 283, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "mixed", + span: Span { + start: 278, + end: 283, + }, }, - }, - ), - value: Literal( - String( - "Hello, 世界!", ), - Span { - start: 287, + value: Literal( + String( + "Hello, 世界!", + ), + Span { + start: 287, + end: 303, + }, + ), + span: Span { + start: 278, end: 303, }, - ), - span: Span { - start: 278, - end: 303, }, }, ], @@ -108,7 +132,7 @@ Module { start: 180, end: 303, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__value_type_multi_expr_method_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__value_type_multi_expr_method_parser.snap index 38a91f77f..4503d3fae 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__value_type_multi_expr_method_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__value_type_multi_expr_method_parser.snap @@ -53,76 +53,88 @@ Module { }, ], body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 558, + end: 568, + }, + }, span: Span { start: 558, end: 568, }, }, + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 569, + end: 574, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "x", + span: Span { + start: 575, + end: 576, + }, + }, + ), + ], + is_cast: false, span: Span { start: 558, - end: 568, + end: 576, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 569, - end: 574, - }, - }, - ], - ), - arguments: [ - Identifier( + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { name: "x", span: Span { - start: 575, - end: 576, + start: 581, + end: 582, }, }, ), - ], - is_cast: false, - span: Span { - start: 558, - end: 576, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 581, - end: 582, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 585, - end: 586, - }, + selector: Binary( + "*", ), - ], - is_cast: false, - span: Span { - start: 581, - end: 586, + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 585, + end: 586, + }, + ), + ], + is_cast: false, + span: Span { + start: 581, + end: 586, + }, }, }, ], @@ -181,94 +193,112 @@ Module { }, ], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "a", - span: Span { - start: 683, - end: 684, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "b", + name: "a", span: Span { - start: 687, - end: 688, + start: 683, + end: 684, }, }, ), - ], - is_cast: false, - span: Span { - start: 683, - end: 688, + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "b", + span: Span { + start: 687, + end: 688, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 683, + end: 688, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "a", - span: Span { - start: 693, - end: 694, - }, - }, - ), - selector: Binary( - "-", - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "b", + name: "a", span: Span { - start: 697, - end: 698, + start: 693, + end: 694, }, }, ), - ], - is_cast: false, - span: Span { - start: 693, - end: 698, + selector: Binary( + "-", + ), + arguments: [ + Identifier( + Identifier { + name: "b", + span: Span { + start: 697, + end: 698, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 693, + end: 698, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "a", - span: Span { - start: 703, - end: 704, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "b", + name: "a", span: Span { - start: 707, - end: 708, + start: 703, + end: 704, }, }, ), - ], - is_cast: false, - span: Span { - start: 703, - end: 708, + selector: Binary( + "*", + ), + arguments: [ + Identifier( + Identifier { + name: "b", + span: Span { + start: 707, + end: 708, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 703, + end: 708, + }, }, }, ], @@ -305,7 +335,7 @@ Module { start: 443, end: 708, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__value_type_param_collision_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__value_type_param_collision_parser.snap index 5ee640539..1011cda8a 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__value_type_param_collision_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__value_type_param_collision_parser.snap @@ -53,64 +53,76 @@ Module { }, ], body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "_seq0", - span: Span { - start: 780, - end: 785, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 788, - end: 789, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "_seq0", + span: Span { + start: 780, + end: 785, + }, }, ), - ], - is_cast: false, - span: Span { - start: 780, - end: 789, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 788, + end: 789, + }, + ), + ], + is_cast: false, + span: Span { + start: 780, + end: 789, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "_seq0", - span: Span { - start: 794, - end: 799, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 802, - end: 803, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "_seq0", + span: Span { + start: 794, + end: 799, + }, }, ), - ], - is_cast: false, - span: Span { - start: 794, - end: 803, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 802, + end: 803, + }, + ), + ], + is_cast: false, + span: Span { + start: 794, + end: 803, + }, }, }, ], @@ -147,7 +159,7 @@ Module { start: 445, end: 803, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__while_true_simple_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__while_true_simple_parser.snap index 2b6e664f0..e37d91d0e 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__while_true_simple_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__while_true_simple_parser.snap @@ -7,1596 +7,1890 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "test", - span: Span { - start: 125, - end: 129, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "test", + span: Span { + start: 125, + end: 129, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "count", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "count", + span: Span { + start: 139, + end: 144, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 148, + end: 149, + }, + ), span: Span { start: 139, - end: 144, + end: 149, }, }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 148, - end: 149, - }, - ), - span: Span { - start: 139, - end: 149, }, - }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "count", - span: Span { - start: 156, - end: 161, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 3, - ), - Span { - start: 164, - end: 165, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "count", + span: Span { + start: 156, + end: 161, + }, + }, + ), + selector: Binary( + "<", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 164, + end: 165, + }, + ), + ], + is_cast: false, + span: Span { + start: 156, + end: 165, + }, }, - ), + }, ], - is_cast: false, span: Span { - start: 156, - end: 165, + start: 155, + end: 166, }, }, - ], - span: Span { - start: 155, - end: 166, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 167, - end: 177, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "count", - span: Span { - start: 179, - end: 184, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "count", - span: Span { - start: 188, - end: 193, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 167, + end: 177, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + expression: Assignment { + target: Identifier( + Identifier { + name: "count", + span: Span { + start: 179, + end: 184, + }, + }, ), - Span { - start: 196, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "count", + span: Span { + start: 188, + end: 193, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 196, + end: 197, + }, + ), + ], + is_cast: false, + span: Span { + start: 188, + end: 197, + }, + }, + span: Span { + start: 179, end: 197, }, - ), - ], - is_cast: false, - span: Span { - start: 188, - end: 197, + }, }, - }, + ], span: Span { - start: 179, - end: 197, + start: 178, + end: 198, }, }, - ], - span: Span { - start: 178, - end: 198, - }, + ), + ], + is_cast: false, + span: Span { + start: 155, + end: 198, }, - ), - ], - is_cast: false, - span: Span { - start: 155, - end: 198, + }, }, - }, - Return { - value: Identifier( - Identifier { - name: "count", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "count", + span: Span { + start: 205, + end: 210, + }, + }, + ), span: Span { - start: 205, + start: 204, end: 210, }, }, - ), - span: Span { - start: 204, - end: 210, }, + ], + span: Span { + start: 133, + end: 212, }, - ], - span: Span { - start: 133, - end: 212, }, + ), + span: Span { + start: 125, + end: 212, }, - ), - span: Span { - start: 125, - end: 212, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testLocal", - span: Span { - start: 250, - end: 259, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testLocal", + span: Span { + start: 250, + end: 259, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 269, - end: 270, - }, - }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 274, - end: 275, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - span: Span { - start: 269, - end: 275, - }, - }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 282, - end: 283, - }, - }, - ), - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 286, - end: 287, - }, - ), - ], - is_cast: false, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", span: Span { - start: 282, - end: 287, + start: 269, + end: 270, }, }, - ], + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 274, + end: 275, + }, + ), span: Span { - start: 281, - end: 288, + start: 269, + end: 275, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 289, - end: 299, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 301, - end: 302, - }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 306, - end: 307, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 310, - end: 311, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 282, + end: 283, + }, }, ), - ], - is_cast: false, - span: Span { - start: 306, - end: 311, + selector: Binary( + "<", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 286, + end: 287, + }, + ), + ], + is_cast: false, + span: Span { + start: 282, + end: 287, + }, }, }, - span: Span { - start: 301, - end: 311, - }, + ], + span: Span { + start: 281, + end: 288, }, - ], - span: Span { - start: 300, - end: 312, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 281, - end: 312, - }, - }, - Return { - value: Identifier( - Identifier { - name: "x", - span: Span { - start: 319, - end: 320, - }, - }, - ), - span: Span { - start: 318, - end: 320, - }, - }, - ], - span: Span { - start: 263, - end: 322, - }, - }, - ), - span: Span { - start: 250, - end: 322, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "testBlockParam", - span: Span { - start: 383, - end: 397, - }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 407, - end: 413, - }, - }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [ - BlockParameter { - name: "x", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", span: Span { - start: 419, - end: 420, + start: 289, + end: 299, }, }, ], - body: [ - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 301, + end: 302, + }, + }, + ), + value: MessageSend { receiver: Identifier( Identifier { name: "x", span: Span { - start: 433, - end: 434, + start: 306, + end: 307, }, }, ), selector: Binary( - "<", + "+", ), arguments: [ Literal( Integer( - 5, + 1, ), Span { - start: 437, - end: 438, + start: 310, + end: 311, }, ), ], is_cast: false, span: Span { - start: 433, - end: 438, + start: 306, + end: 311, }, }, - ], + span: Span { + start: 301, + end: 311, + }, + }, + }, + ], + span: Span { + start: 300, + end: 312, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 281, + end: 312, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "x", + span: Span { + start: 319, + end: 320, + }, + }, + ), + span: Span { + start: 318, + end: 320, + }, + }, + }, + ], + span: Span { + start: 263, + end: 322, + }, + }, + ), + span: Span { + start: 250, + end: 322, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testBlockParam", + span: Span { + start: 383, + end: 397, + }, + }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 407, + end: 413, + }, + }, + ), + value: MessageSend { + receiver: Block( + Block { + parameters: [ + BlockParameter { + name: "x", span: Span { - start: 432, - end: 439, + start: 419, + end: 420, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 440, - end: 450, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 452, - end: 453, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "x", + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 433, + end: 434, + }, + }, + ), + selector: Binary( + "<", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 437, + end: 438, + }, + ), + ], + is_cast: false, span: Span { - start: 457, - end: 458, + start: 433, + end: 438, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 461, - end: 462, + }, + ], + span: Span { + start: 432, + end: 439, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 440, + end: 450, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 452, + end: 453, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 457, + end: 458, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 461, + end: 462, + }, + ), + ], + is_cast: false, + span: Span { + start: 457, + end: 462, + }, + }, + span: Span { + start: 452, + end: 462, + }, }, - ), + }, ], - is_cast: false, span: Span { - start: 457, - end: 462, + start: 451, + end: 463, }, }, - span: Span { - start: 452, - end: 462, - }, - }, + ), ], + is_cast: false, span: Span { - start: 451, + start: 432, end: 463, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "x", + span: Span { + start: 473, + end: 474, + }, + }, + ), + }, ], - is_cast: false, span: Span { - start: 432, - end: 463, + start: 417, + end: 480, }, }, - Identifier( - Identifier { - name: "x", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", span: Span { - start: 473, - end: 474, + start: 481, + end: 487, }, }, + ], + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 488, + end: 489, + }, ), ], + is_cast: false, span: Span { start: 417, - end: 480, + end: 489, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + span: Span { + start: 407, + end: 489, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "result", span: Span { - start: 481, - end: 487, + start: 496, + end: 502, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 488, - end: 489, - }, ), - ], - is_cast: false, - span: Span { - start: 417, - end: 489, - }, - }, - span: Span { - start: 407, - end: 489, - }, - }, - Return { - value: Identifier( - Identifier { - name: "result", span: Span { - start: 496, + start: 495, end: 502, }, }, - ), - span: Span { - start: 495, - end: 502, }, + ], + span: Span { + start: 401, + end: 504, }, - ], - span: Span { - start: 401, - end: 504, }, + ), + span: Span { + start: 383, + end: 504, }, - ), - span: Span { - start: 383, - end: 504, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testBlockParamWhileFalse", - span: Span { - start: 579, - end: 603, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testBlockParamWhileFalse", + span: Span { + start: 579, + end: 603, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 613, - end: 619, - }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 625, - end: 626, - }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 613, + end: 619, }, - ], - body: [ - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "n", - span: Span { - start: 638, - end: 639, - }, - }, - ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 644, - end: 645, - }, - ), - ], - is_cast: false, - span: Span { - start: 638, - end: 645, - }, - }, - ], + }, + ), + value: MessageSend { + receiver: Block( + Block { + parameters: [ + BlockParameter { + name: "n", span: Span { - start: 637, - end: 646, + start: 625, + end: 626, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileFalse:", - span: Span { - start: 647, - end: 658, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "n", - span: Span { - start: 660, - end: 661, + expression: MessageSend { + receiver: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "n", + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 638, + end: 639, + }, + }, + ), + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 644, + end: 645, + }, + ), + ], + is_cast: false, span: Span { - start: 665, - end: 666, + start: 638, + end: 645, }, }, - ), - selector: Binary( - "-", - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 669, - end: 670, + }, + ], + span: Span { + start: 637, + end: 646, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "whileFalse:", + span: Span { + start: 647, + end: 658, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "n", + span: Span { + start: 660, + end: 661, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 665, + end: 666, + }, + }, + ), + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 669, + end: 670, + }, + ), + ], + is_cast: false, + span: Span { + start: 665, + end: 670, + }, + }, + span: Span { + start: 660, + end: 670, + }, }, - ), + }, ], - is_cast: false, span: Span { - start: 665, - end: 670, + start: 659, + end: 671, }, }, - span: Span { - start: 660, - end: 670, - }, - }, + ), ], + is_cast: false, span: Span { - start: 659, + start: 637, end: 671, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "n", + span: Span { + start: 681, + end: 682, + }, + }, + ), + }, ], - is_cast: false, span: Span { - start: 637, - end: 671, + start: 623, + end: 688, }, }, - Identifier( - Identifier { - name: "n", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", span: Span { - start: 681, - end: 682, + start: 689, + end: 695, }, }, + ], + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 696, + end: 697, + }, ), ], + is_cast: false, span: Span { start: 623, - end: 688, + end: 697, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + span: Span { + start: 613, + end: 697, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "result", span: Span { - start: 689, - end: 695, + start: 704, + end: 710, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 696, - end: 697, - }, ), - ], - is_cast: false, - span: Span { - start: 623, - end: 697, - }, - }, - span: Span { - start: 613, - end: 697, - }, - }, - Return { - value: Identifier( - Identifier { - name: "result", span: Span { - start: 704, + start: 703, end: 710, }, }, - ), - span: Span { - start: 703, - end: 710, }, + ], + span: Span { + start: 607, + end: 712, }, - ], - span: Span { - start: 607, - end: 712, }, + ), + span: Span { + start: 579, + end: 712, }, - ), - span: Span { - start: 579, - end: 712, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testTimesRepeat", - span: Span { - start: 759, - end: 774, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testTimesRepeat", + span: Span { + start: 759, + end: 774, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 784, + end: 791, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 795, + end: 796, + }, + ), span: Span { start: 784, - end: 791, + end: 796, }, }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 795, - end: 796, - }, - ), - span: Span { - start: 784, - end: 796, }, - }, - MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 802, - end: 803, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "timesRepeat:", - span: Span { - start: 804, - end: 816, + expression: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 802, + end: 803, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 818, - end: 825, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 829, - end: 836, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "timesRepeat:", + span: Span { + start: 804, + end: 816, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 818, + end: 825, + }, + }, ), - Span { - start: 839, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 829, + end: 836, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 839, + end: 840, + }, + ), + ], + is_cast: false, + span: Span { + start: 829, + end: 840, + }, + }, + span: Span { + start: 818, end: 840, }, - ), - ], - is_cast: false, - span: Span { - start: 829, - end: 840, + }, }, - }, + ], span: Span { - start: 818, - end: 840, + start: 817, + end: 841, }, }, - ], - span: Span { - start: 817, - end: 841, + ), + ], + is_cast: false, + span: Span { + start: 802, + end: 841, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "counter", + span: Span { + start: 848, + end: 855, + }, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 802, - end: 841, - }, - }, - Return { - value: Identifier( - Identifier { - name: "counter", + ), span: Span { - start: 848, + start: 847, end: 855, }, }, - ), - span: Span { - start: 847, - end: 855, }, + ], + span: Span { + start: 778, + end: 857, }, - ], - span: Span { - start: 778, - end: 857, }, + ), + span: Span { + start: 759, + end: 857, }, - ), - span: Span { - start: 759, - end: 857, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testTimesRepeatBlockParam", - span: Span { - start: 920, - end: 945, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testTimesRepeatBlockParam", + span: Span { + start: 920, + end: 945, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 955, - end: 961, - }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 967, - end: 968, - }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 955, + end: 961, }, - ], - body: [ - MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 979, - end: 980, + }, + ), + value: MessageSend { + receiver: Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 967, + end: 968, + }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "timesRepeat:", - span: Span { - start: 981, - end: 993, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "n", - span: Span { - start: 995, - end: 996, - }, + expression: MessageSend { + receiver: Literal( + Integer( + 3, + ), + Span { + start: 979, + end: 980, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "timesRepeat:", + span: Span { + start: 981, + end: 993, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "n", - span: Span { - start: 1000, - end: 1001, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 10, - ), - Span { - start: 1004, - end: 1006, + expression: Assignment { + target: Identifier( + Identifier { + name: "n", + span: Span { + start: 995, + end: 996, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 1000, + end: 1001, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 1004, + end: 1006, + }, + ), + ], + is_cast: false, + span: Span { + start: 1000, + end: 1006, + }, + }, + span: Span { + start: 995, + end: 1006, + }, }, - ), + }, ], - is_cast: false, span: Span { - start: 1000, - end: 1006, + start: 994, + end: 1007, }, }, - span: Span { - start: 995, - end: 1006, - }, - }, + ), ], + is_cast: false, span: Span { - start: 994, + start: 979, end: 1007, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "n", + span: Span { + start: 1017, + end: 1018, + }, + }, + ), + }, ], - is_cast: false, span: Span { - start: 979, - end: 1007, + start: 965, + end: 1024, }, }, - Identifier( - Identifier { - name: "n", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", span: Span { - start: 1017, - end: 1018, + start: 1025, + end: 1031, }, }, + ], + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 1032, + end: 1033, + }, ), ], + is_cast: false, span: Span { start: 965, - end: 1024, + end: 1033, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + span: Span { + start: 955, + end: 1033, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "result", span: Span { - start: 1025, - end: 1031, + start: 1040, + end: 1046, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 1032, - end: 1033, - }, ), - ], - is_cast: false, - span: Span { - start: 965, - end: 1033, - }, - }, - span: Span { - start: 955, - end: 1033, - }, - }, - Return { - value: Identifier( - Identifier { - name: "result", span: Span { - start: 1040, + start: 1039, end: 1046, }, }, - ), - span: Span { - start: 1039, - end: 1046, }, + ], + span: Span { + start: 949, + end: 1048, }, - ], - span: Span { - start: 949, - end: 1048, }, + ), + span: Span { + start: 920, + end: 1048, }, - ), - span: Span { - start: 920, - end: 1048, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testToDo", - span: Span { - start: 1089, - end: 1097, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testToDo", + span: Span { + start: 1089, + end: 1097, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "total", + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "total", + span: Span { + start: 1107, + end: 1112, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 1116, + end: 1117, + }, + ), span: Span { start: 1107, - end: 1112, + end: 1117, }, }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 1116, - end: 1117, - }, - ), - span: Span { - start: 1107, - end: 1117, }, - }, - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 1123, - end: 1124, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", - span: Span { - start: 1125, - end: 1128, - }, - }, - KeywordPart { - keyword: "do:", - span: Span { - start: 1132, - end: 1135, + expression: MessageSend { + receiver: Literal( + Integer( + 1, + ), + Span { + start: 1123, + end: 1124, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 10, ), - Span { - start: 1129, - end: 1131, - }, - ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 1125, + end: 1128, + }, + }, + KeywordPart { + keyword: "do:", span: Span { - start: 1138, - end: 1139, + start: 1132, + end: 1135, }, }, ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "total", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 1129, + end: 1131, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", span: Span { - start: 1142, - end: 1147, + start: 1138, + end: 1139, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "total", - span: Span { - start: 1151, - end: 1156, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "n", + expression: Assignment { + target: Identifier( + Identifier { + name: "total", + span: Span { + start: 1142, + end: 1147, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "total", + span: Span { + start: 1151, + end: 1156, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 1159, + end: 1160, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 1159, + start: 1151, end: 1160, }, }, - ), - ], - is_cast: false, - span: Span { - start: 1151, - end: 1160, + span: Span { + start: 1142, + end: 1160, + }, + }, }, - }, + ], span: Span { - start: 1142, - end: 1160, + start: 1136, + end: 1161, }, }, - ], - span: Span { - start: 1136, - end: 1161, - }, + ), + ], + is_cast: false, + span: Span { + start: 1123, + end: 1161, }, - ), - ], - is_cast: false, - span: Span { - start: 1123, - end: 1161, + }, }, - }, - Return { - value: Identifier( - Identifier { - name: "total", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "total", + span: Span { + start: 1168, + end: 1173, + }, + }, + ), span: Span { - start: 1168, + start: 1167, end: 1173, }, }, - ), - span: Span { - start: 1167, - end: 1173, }, + ], + span: Span { + start: 1101, + end: 1175, }, - ], - span: Span { - start: 1101, - end: 1175, }, + ), + span: Span { + start: 1089, + end: 1175, }, - ), - span: Span { - start: 1089, - end: 1175, }, }, - Assignment { - target: Identifier( - Identifier { - name: "testToDoBlockParam", - span: Span { - start: 1232, - end: 1250, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "testToDoBlockParam", + span: Span { + start: 1232, + end: 1250, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 1260, - end: 1266, - }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 1272, - end: 1273, - }, - }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 1284, - end: 1287, - }, - }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 1291, - end: 1292, - }, - ), - span: Span { - start: 1284, - end: 1292, - }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result", + span: Span { + start: 1260, + end: 1266, }, - MessageSend { - receiver: Identifier( - Identifier { + }, + ), + value: MessageSend { + receiver: Block( + Block { + parameters: [ + BlockParameter { name: "x", span: Span { - start: 1302, - end: 1303, + start: 1272, + end: 1273, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", - span: Span { - start: 1304, - end: 1307, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - KeywordPart { - keyword: "do:", + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", + span: Span { + start: 1284, + end: 1287, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 1291, + end: 1292, + }, + ), span: Span { - start: 1310, - end: 1313, + start: 1284, + end: 1292, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 1308, - end: 1309, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Block( - Block { - parameters: [ - BlockParameter { - name: "i", + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", span: Span { - start: 1316, - end: 1317, + start: 1302, + end: 1303, }, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 1320, - end: 1323, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 1304, + end: 1307, + }, + }, + KeywordPart { + keyword: "do:", + span: Span { + start: 1310, + end: 1313, }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 5, ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "sum", + Span { + start: 1308, + end: 1309, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "i", span: Span { - start: 1327, - end: 1330, + start: 1316, + end: 1317, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "i", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", + span: Span { + start: 1320, + end: 1323, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "sum", + span: Span { + start: 1327, + end: 1330, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "i", + span: Span { + start: 1333, + end: 1334, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1327, + end: 1334, + }, + }, span: Span { - start: 1333, + start: 1320, end: 1334, }, }, - ), + }, ], - is_cast: false, span: Span { - start: 1327, - end: 1334, + start: 1314, + end: 1335, }, }, - span: Span { - start: 1320, - end: 1334, - }, - }, + ), ], + is_cast: false, span: Span { - start: 1314, + start: 1302, end: 1335, }, }, - ), + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "sum", + span: Span { + start: 1345, + end: 1348, + }, + }, + ), + }, ], - is_cast: false, span: Span { - start: 1302, - end: 1335, + start: 1270, + end: 1354, }, }, - Identifier( - Identifier { - name: "sum", + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", span: Span { - start: 1345, - end: 1348, + start: 1355, + end: 1361, }, }, + ], + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1362, + end: 1363, + }, ), ], + is_cast: false, span: Span { start: 1270, - end: 1354, + end: 1363, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + span: Span { + start: 1260, + end: 1363, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Return { + value: Identifier( + Identifier { + name: "result", span: Span { - start: 1355, - end: 1361, + start: 1370, + end: 1376, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 1, - ), - Span { - start: 1362, - end: 1363, - }, ), - ], - is_cast: false, - span: Span { - start: 1270, - end: 1363, - }, - }, - span: Span { - start: 1260, - end: 1363, - }, - }, - Return { - value: Identifier( - Identifier { - name: "result", span: Span { - start: 1370, + start: 1369, end: 1376, }, }, - ), - span: Span { - start: 1369, - end: 1376, }, + ], + span: Span { + start: 1254, + end: 1378, }, - ], - span: Span { - start: 1254, - end: 1378, }, + ), + span: Span { + start: 1232, + end: 1378, }, - ), - span: Span { - start: 1232, - end: 1378, }, }, ], @@ -1604,7 +1898,7 @@ Module { start: 125, end: 1379, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__whitespace_handling_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__whitespace_handling_parser.snap index 9902b0a29..2cfc59035 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__whitespace_handling_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__whitespace_handling_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,241 +7,277 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "x", - span: Span { - start: 155, - end: 156, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 166, - end: 167, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "x", + span: Span { + start: 155, + end: 156, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 3, + 5, ), Span { - start: 174, - end: 175, + start: 166, + end: 167, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 174, + end: 175, + }, + ), + ], + is_cast: false, + span: Span { + start: 166, + end: 175, + }, + }, span: Span { - start: 166, + start: 155, end: 175, }, }, - span: Span { - start: 155, - end: 175, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "y", - span: Span { - start: 202, - end: 203, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 207, - end: 209, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "y", + span: Span { + start: 202, + end: 203, + }, }, ), - selector: Binary( - "*", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 2, + 10, ), Span { - start: 212, - end: 213, + start: 207, + end: 209, }, ), - ], - is_cast: false, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 212, + end: 213, + }, + ), + ], + is_cast: false, + span: Span { + start: 207, + end: 213, + }, + }, span: Span { - start: 207, + start: 202, end: 213, }, }, - span: Span { - start: 202, - end: 213, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 238, - end: 244, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "x", + name: "result", span: Span { - start: 248, - end: 249, + start: 238, + end: 244, }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + value: MessageSend { + receiver: Identifier( Identifier { - name: "y", + name: "x", span: Span { - start: 252, - end: 253, + start: 248, + end: 249, }, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "y", + span: Span { + start: 252, + end: 253, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 248, + end: 253, + }, + }, span: Span { - start: 248, + start: 238, end: 253, }, }, - span: Span { - start: 238, - end: 253, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "z", - span: Span { - start: 291, - end: 292, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "z", + span: Span { + start: 291, + end: 292, + }, }, - }, - ), - value: Literal( - Integer( - 100, ), - Span { - start: 296, + value: Literal( + Integer( + 100, + ), + Span { + start: 296, + end: 299, + }, + ), + span: Span { + start: 291, end: 299, }, - ), - span: Span { - start: 291, - end: 299, }, }, - Assignment { - target: Identifier( - Identifier { - name: "leadingSpace", - span: Span { - start: 330, - end: 342, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "leadingSpace", + span: Span { + start: 330, + end: 342, + }, + }, + ), + value: Literal( + Integer( + 42, + ), + Span { + start: 346, + end: 348, }, - }, - ), - value: Literal( - Integer( - 42, ), - Span { - start: 346, + span: Span { + start: 330, end: 348, }, - ), - span: Span { - start: 330, - end: 348, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "object", - span: Span { - start: 381, - end: 387, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "message:", - span: Span { - start: 391, - end: 399, - }, - }, - KeywordPart { - keyword: "with:", - span: Span { - start: 414, - end: 419, - }, - }, - ], - ), - arguments: [ - Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( Identifier { - name: "argument", + name: "object", span: Span { - start: 402, - end: 410, + start: 381, + end: 387, }, }, ), - Identifier( - Identifier { - name: "another", - span: Span { - start: 421, - end: 428, + selector: Keyword( + [ + KeywordPart { + keyword: "message:", + span: Span { + start: 391, + end: 399, + }, }, - }, + KeywordPart { + keyword: "with:", + span: Span { + start: 414, + end: 419, + }, + }, + ], ), - ], - is_cast: false, - span: Span { - start: 381, - end: 428, + arguments: [ + Identifier( + Identifier { + name: "argument", + span: Span { + start: 402, + end: 410, + }, + }, + ), + Identifier( + Identifier { + name: "another", + span: Span { + start: 421, + end: 428, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 381, + end: 428, + }, }, }, ], @@ -250,7 +285,7 @@ Module { start: 155, end: 428, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_cascade_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_cascade_parser.snap index 733cbcf41..e6d3f3f42 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_cascade_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_cascade_parser.snap @@ -34,68 +34,33 @@ Module { ), parameters: [], body: [ - Cascade { - receiver: MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Cascade { + receiver: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 162, + end: 172, + }, + }, span: Span { start: 162, end: 172, }, }, - span: Span { - start: 162, - end: 172, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 173, - end: 178, - }, - }, - ], - ), - arguments: [ - Literal( - String( - "Hello", - ), - Span { - start: 179, - end: 186, - }, - ), - ], - is_cast: false, - span: Span { - start: 162, - end: 186, - }, - }, - messages: [ - CascadeMessage { - selector: Unary( - "cr", - ), - arguments: [], - span: Span { - start: 188, - end: 190, - }, - }, - CascadeMessage { selector: Keyword( [ KeywordPart { keyword: "show:", span: Span { - start: 192, - end: 197, + start: 173, + end: 178, }, }, ], @@ -103,23 +68,64 @@ Module { arguments: [ Literal( String( - "World", + "Hello", ), Span { - start: 198, - end: 205, + start: 179, + end: 186, }, ), ], + is_cast: false, span: Span { - start: 192, - end: 205, + start: 162, + end: 186, + }, + }, + messages: [ + CascadeMessage { + selector: Unary( + "cr", + ), + arguments: [], + span: Span { + start: 188, + end: 190, + }, + }, + CascadeMessage { + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 192, + end: 197, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "World", + ), + Span { + start: 198, + end: 205, + }, + ), + ], + span: Span { + start: 192, + end: 205, + }, }, + ], + span: Span { + start: 162, + end: 205, }, - ], - span: Span { - start: 162, - end: 205, }, }, ], @@ -156,7 +162,7 @@ Module { start: 130, end: 205, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// BT-374: Workspace binding cascade dispatch.", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_send_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_send_parser.snap index f2f846f61..92fae0841 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_send_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__workspace_binding_send_parser.snap @@ -34,47 +34,53 @@ Module { ), parameters: [], body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 183, + end: 193, + }, + }, span: Span { start: 183, end: 193, }, }, + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 194, + end: 199, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "Hello, World!", + ), + Span { + start: 200, + end: 215, + }, + ), + ], + is_cast: false, span: Span { start: 183, - end: 193, + end: 215, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 194, - end: 199, - }, - }, - ], - ), - arguments: [ - Literal( - String( - "Hello, World!", - ), - Span { - start: 200, - end: 215, - }, - ), - ], - is_cast: false, - span: Span { - start: 183, - end: 215, - }, }, ], return_type: None, @@ -110,7 +116,7 @@ Module { start: 148, end: 215, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// BT-374: Workspace binding dispatch via persistent_term.", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_array_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_array_parser.snap index f64cbb3f9..18fcbedb5 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_array_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_array_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,140 +7,224 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "point", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "point", + span: Span { + start: 122, + end: 127, + }, + }, + ), + value: Error { + message: "Unexpected token: expected expression, found {", span: Span { - start: 122, - end: 127, + start: 131, + end: 132, }, }, - ), - value: Error { - message: "Unexpected token: expected expression, found {", span: Span { - start: 131, + start: 122, end: 132, }, }, - span: Span { - start: 122, - end: 132, - }, }, - Literal( - Integer( - 10, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 10, + ), + Span { + start: 132, + end: 134, + }, ), - Span { - start: 132, - end: 134, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Error { - message: "Unexpected token: expected expression, found ,", - span: Span { - start: 134, - end: 135, + expression: Error { + message: "Unexpected token: expected expression, found ,", + span: Span { + start: 134, + end: 135, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 138, - end: 139, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 159, - end: 160, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 138, + end: 139, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 171, - end: 172, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 159, + end: 160, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 423, - end: 424, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 171, + end: 172, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 479, - end: 480, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 423, + end: 424, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 529, - end: 530, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 479, + end: 480, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 590, - end: 591, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 529, + end: 530, + }, }, }, - MessageSend { - receiver: Error { - message: "Unexpected token: expected expression, found }", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", span: Span { - start: 675, - end: 676, + start: 590, + end: 591, }, }, - selector: Binary( - "++", - ), - arguments: [ - Error { - message: "Unexpected token: expected expression, found {", + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found }", span: Span { - start: 680, - end: 681, + start: 675, + end: 676, }, }, - ], - is_cast: false, - span: Span { - start: 675, - end: 681, + selector: Binary( + "++", + ), + arguments: [ + Error { + message: "Unexpected token: expected expression, found {", + span: Span { + start: 680, + end: 681, + }, + }, + ], + is_cast: false, + span: Span { + start: 675, + end: 681, + }, }, }, - Literal( - Integer( - 3, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 3, + ), + Span { + start: 681, + end: 682, + }, ), - Span { - start: 681, - end: 682, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - Error { - message: "Unexpected token: expected expression, found ,", - span: Span { - start: 682, - end: 683, + expression: Error { + message: "Unexpected token: expected expression, found ,", + span: Span { + start: 682, + end: 683, + }, }, }, - Error { - message: "Unexpected token: expected expression, found }", - span: Span { - start: 685, - end: 686, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found }", + span: Span { + start: 685, + end: 686, + }, }, }, ], @@ -149,7 +232,7 @@ Module { start: 122, end: 732, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_block_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_block_parser.snap index 9e54c0171..c1aa00da6 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_block_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_block_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,595 +7,697 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "block", - span: Span { - start: 140, - end: 145, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "block", + span: Span { + start: 140, + end: 145, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 150, - end: 152, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 150, + end: 152, + }, + ), }, - ), - ], - span: Span { - start: 149, - end: 153, + ], + span: Span { + start: 149, + end: 153, + }, }, + ), + span: Span { + start: 140, + end: 153, }, - ), - span: Span { - start: 140, - end: 153, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result", - span: Span { - start: 154, - end: 160, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "block", + name: "result", span: Span { - start: 164, - end: 169, + start: 154, + end: 160, }, }, ), - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "block", + span: Span { + start: 164, + end: 169, + }, + }, + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 164, + end: 175, + }, + }, span: Span { - start: 164, + start: 154, end: 175, }, }, - span: Span { - start: 154, - end: 175, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "increment", - span: Span { - start: 204, - end: 213, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "increment", + span: Span { + start: 204, + end: 213, + }, }, - }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 219, - end: 220, + ), + value: Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 219, + end: 220, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 223, - end: 224, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 223, + end: 224, + }, + }, ), - Span { - start: 227, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 227, + end: 228, + }, + ), + ], + is_cast: false, + span: Span { + start: 223, end: 228, }, - ), - ], - is_cast: false, - span: Span { - start: 223, - end: 228, + }, }, + ], + span: Span { + start: 217, + end: 229, }, - ], - span: Span { - start: 217, - end: 229, }, + ), + span: Span { + start: 204, + end: 229, }, - ), - span: Span { - start: 204, - end: 229, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 230, - end: 237, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "increment", + name: "result2", span: Span { - start: 241, - end: 250, + start: 230, + end: 237, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "increment", span: Span { - start: 251, - end: 257, + start: 241, + end: 250, }, }, - ], - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 258, - end: 259, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 251, + end: 257, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 258, + end: 259, + }, + ), + ], + is_cast: false, + span: Span { + start: 241, + end: 259, + }, + }, span: Span { - start: 241, + start: 230, end: 259, }, }, - span: Span { - start: 230, - end: 259, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "add", - span: Span { - start: 289, - end: 292, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "add", + span: Span { + start: 289, + end: 292, + }, }, - }, - ), - value: Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 298, - end: 299, + ), + value: Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 298, + end: 299, + }, }, - }, - BlockParameter { - name: "y", - span: Span { - start: 301, - end: 302, + BlockParameter { + name: "y", + span: Span { + start: 301, + end: 302, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 305, + end: 306, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "y", + span: Span { + start: 309, + end: 310, + }, + }, + ), + ], + is_cast: false, span: Span { start: 305, - end: 306, + end: 310, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "y", - span: Span { - start: 309, - end: 310, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 305, - end: 310, }, + ], + span: Span { + start: 296, + end: 311, }, - ], - span: Span { - start: 296, - end: 311, }, + ), + span: Span { + start: 289, + end: 311, }, - ), - span: Span { - start: 289, - end: 311, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result3", - span: Span { - start: 312, - end: 319, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "add", + name: "result3", span: Span { - start: 323, - end: 326, + start: 312, + end: 319, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "value:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "add", span: Span { - start: 327, - end: 333, + start: 323, + end: 326, }, }, - KeywordPart { - keyword: "value:", - span: Span { - start: 336, - end: 342, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "value:", + span: Span { + start: 327, + end: 333, + }, }, - }, - ], - ), - arguments: [ - Literal( - Integer( - 3, - ), - Span { - start: 334, - end: 335, - }, + KeywordPart { + keyword: "value:", + span: Span { + start: 336, + end: 342, + }, + }, + ], ), - Literal( - Integer( - 4, + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 334, + end: 335, + }, ), - Span { - start: 343, - end: 344, - }, - ), - ], - is_cast: false, + Literal( + Integer( + 4, + ), + Span { + start: 343, + end: 344, + }, + ), + ], + is_cast: false, + span: Span { + start: 323, + end: 344, + }, + }, span: Span { - start: 323, + start: 312, end: 344, }, }, - span: Span { - start: 312, - end: 344, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 360, - end: 367, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 360, + end: 367, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 371, + end: 372, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 371, + span: Span { + start: 360, end: 372, }, - ), - span: Span { - start: 360, - end: 372, }, }, - MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 374, - end: 381, - }, - }, - ), - selector: Binary( - "<", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 384, - end: 385, - }, - ), - ], - is_cast: false, - span: Span { - start: 374, - end: 385, - }, - }, - ], - span: Span { - start: 373, - end: 386, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "whileTrue:", - span: Span { - start: 387, - end: 397, - }, - }, - ], - ), - arguments: [ - Block( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Block( Block { parameters: [], body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 399, - end: 406, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "counter", span: Span { - start: 410, - end: 417, + start: 374, + end: 381, }, }, ), selector: Binary( - "+", + "<", ), arguments: [ Literal( Integer( - 1, + 5, ), Span { - start: 420, - end: 421, + start: 384, + end: 385, }, ), ], is_cast: false, span: Span { - start: 410, - end: 421, + start: 374, + end: 385, }, }, - span: Span { - start: 399, - end: 421, - }, }, ], span: Span { - start: 398, - end: 422, + start: 373, + end: 386, }, }, ), - ], - is_cast: false, - span: Span { - start: 373, - end: 422, + selector: Keyword( + [ + KeywordPart { + keyword: "whileTrue:", + span: Span { + start: 387, + end: 397, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 399, + end: 406, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 410, + end: 417, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 420, + end: 421, + }, + ), + ], + is_cast: false, + span: Span { + start: 410, + end: 421, + }, + }, + span: Span { + start: 399, + end: 421, + }, + }, + }, + ], + span: Span { + start: 398, + end: 422, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 373, + end: 422, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "outer", - span: Span { - start: 452, - end: 457, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "outer", + span: Span { + start: 452, + end: 457, + }, + }, + ), + value: Literal( + Integer( + 10, + ), + Span { + start: 461, + end: 463, }, - }, - ), - value: Literal( - Integer( - 10, ), - Span { - start: 461, + span: Span { + start: 452, end: 463, }, - ), - span: Span { - start: 452, - end: 463, }, }, - Assignment { - target: Identifier( - Identifier { - name: "captureBlock", - span: Span { - start: 464, - end: 476, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "captureBlock", + span: Span { + start: 464, + end: 476, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "outer", - span: Span { - start: 481, - end: 486, - }, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 5, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "outer", + span: Span { + start: 481, + end: 486, + }, + }, ), - Span { - start: 489, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 489, + end: 490, + }, + ), + ], + is_cast: false, + span: Span { + start: 481, end: 490, }, - ), - ], - is_cast: false, - span: Span { - start: 481, - end: 490, + }, }, + ], + span: Span { + start: 480, + end: 491, }, - ], - span: Span { - start: 480, - end: 491, }, + ), + span: Span { + start: 464, + end: 491, }, - ), - span: Span { - start: 464, - end: 491, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result4", - span: Span { - start: 492, - end: 499, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "captureBlock", + name: "result4", span: Span { - start: 503, - end: 515, + start: 492, + end: 499, }, }, ), - selector: Unary( - "value", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "captureBlock", + span: Span { + start: 503, + end: 515, + }, + }, + ), + selector: Unary( + "value", + ), + arguments: [], + is_cast: false, + span: Span { + start: 503, + end: 521, + }, + }, span: Span { - start: 503, + start: 492, end: 521, }, }, - span: Span { - start: 492, - end: 521, - }, }, ], span: Span { start: 140, end: 521, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_boolean_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_boolean_parser.snap index 4a5dcda45..876ded03f 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_boolean_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_boolean_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,750 +7,870 @@ Module { classes: [], method_definitions: [], expressions: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "true", - span: Span { - start: 154, - end: 158, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "true", span: Span { - start: 159, - end: 166, + start: 154, + end: 158, }, }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 192, - end: 200, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 159, + end: 166, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", - span: Span { - start: 168, - end: 178, - }, - }, - span: Span { - start: 168, - end: 178, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 192, + end: 200, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 168, + end: 178, + }, + }, span: Span { - start: 179, - end: 184, + start: 168, + end: 178, }, }, - ], - ), - arguments: [ - Literal( - String( - "yes", + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 179, + end: 184, + }, + }, + ], ), - Span { - start: 185, + arguments: [ + Literal( + String( + "yes", + ), + Span { + start: 185, + end: 190, + }, + ), + ], + is_cast: false, + span: Span { + start: 168, end: 190, }, - ), - ], - is_cast: false, - span: Span { - start: 168, - end: 190, + }, }, + ], + span: Span { + start: 167, + end: 191, }, - ], - span: Span { - start: 167, - end: 191, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", - span: Span { - start: 202, - end: 212, - }, - }, - span: Span { - start: 202, - end: 212, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 202, + end: 212, + }, + }, span: Span { - start: 213, - end: 218, + start: 202, + end: 212, }, }, - ], - ), - arguments: [ - Literal( - String( - "no", + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 213, + end: 218, + }, + }, + ], ), - Span { - start: 219, + arguments: [ + Literal( + String( + "no", + ), + Span { + start: 219, + end: 223, + }, + ), + ], + is_cast: false, + span: Span { + start: 202, end: 223, }, - ), - ], - is_cast: false, - span: Span { - start: 202, - end: 223, + }, }, + ], + span: Span { + start: 201, + end: 224, }, - ], - span: Span { - start: 201, - end: 224, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 154, - end: 224, + ), + ], + is_cast: false, + span: Span { + start: 154, + end: 224, + }, }, }, - MessageSend { - receiver: Identifier( - Identifier { - name: "false", - span: Span { - start: 261, - end: 266, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "false", span: Span { - start: 267, - end: 274, + start: 261, + end: 266, }, }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 300, - end: 308, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 267, + end: 274, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", - span: Span { - start: 276, - end: 286, - }, - }, - span: Span { - start: 276, - end: 286, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 300, + end: 308, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 276, + end: 286, + }, + }, span: Span { - start: 287, - end: 292, + start: 276, + end: 286, }, }, - ], - ), - arguments: [ - Literal( - String( - "yes", + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 287, + end: 292, + }, + }, + ], ), - Span { - start: 293, + arguments: [ + Literal( + String( + "yes", + ), + Span { + start: 293, + end: 298, + }, + ), + ], + is_cast: false, + span: Span { + start: 276, end: 298, }, - ), - ], - is_cast: false, - span: Span { - start: 276, - end: 298, + }, }, + ], + span: Span { + start: 275, + end: 299, }, - ], - span: Span { - start: 275, - end: 299, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", - span: Span { - start: 310, - end: 320, - }, - }, - span: Span { - start: 310, - end: 320, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 310, + end: 320, + }, + }, span: Span { - start: 321, - end: 326, + start: 310, + end: 320, }, }, - ], - ), - arguments: [ - Literal( - String( - "no", + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 321, + end: 326, + }, + }, + ], ), - Span { - start: 327, + arguments: [ + Literal( + String( + "no", + ), + Span { + start: 327, + end: 331, + }, + ), + ], + is_cast: false, + span: Span { + start: 310, end: 331, }, - ), - ], - is_cast: false, - span: Span { - start: 310, - end: 331, + }, }, + ], + span: Span { + start: 309, + end: 332, }, - ], - span: Span { - start: 309, - end: 332, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 261, - end: 332, + ), + ], + is_cast: false, + span: Span { + start: 261, + end: 332, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result1", - span: Span { - start: 354, - end: 361, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result1", span: Span { - start: 365, - end: 369, + start: 354, + end: 361, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "and:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", span: Span { - start: 370, - end: 374, + start: 365, + end: 369, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 376, - end: 380, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 370, + end: 374, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 376, + end: 380, + }, + }, + ), }, - ), - ], - span: Span { - start: 375, - end: 381, + ], + span: Span { + start: 375, + end: 381, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 365, + end: 381, + }, + }, span: Span { - start: 365, + start: 354, end: 381, }, }, - span: Span { - start: 354, - end: 381, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 382, - end: 389, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result2", span: Span { - start: 393, - end: 397, + start: 382, + end: 389, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "and:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", span: Span { - start: 398, - end: 402, + start: 393, + end: 397, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "false", - span: Span { - start: 404, - end: 409, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 398, + end: 402, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "false", + span: Span { + start: 404, + end: 409, + }, + }, + ), }, - ), - ], - span: Span { - start: 403, - end: 410, + ], + span: Span { + start: 403, + end: 410, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 393, + end: 410, + }, + }, span: Span { - start: 393, + start: 382, end: 410, }, }, - span: Span { - start: 382, - end: 410, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result3", - span: Span { - start: 411, - end: 418, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result3", span: Span { - start: 422, - end: 427, + start: 411, + end: 418, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "and:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", span: Span { - start: 428, - end: 432, + start: 422, + end: 427, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 434, - end: 438, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 428, + end: 432, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 434, + end: 438, + }, + }, + ), }, - ), - ], - span: Span { - start: 433, - end: 439, + ], + span: Span { + start: 433, + end: 439, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 422, + end: 439, + }, + }, span: Span { - start: 422, + start: 411, end: 439, }, }, - span: Span { - start: 411, - end: 439, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result4", - span: Span { - start: 460, - end: 467, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result4", span: Span { - start: 471, - end: 475, + start: 460, + end: 467, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "or:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", span: Span { - start: 476, - end: 479, + start: 471, + end: 475, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "false", - span: Span { - start: 481, - end: 486, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 476, + end: 479, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "false", + span: Span { + start: 481, + end: 486, + }, + }, + ), }, - ), - ], - span: Span { - start: 480, - end: 487, + ], + span: Span { + start: 480, + end: 487, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 471, + end: 487, + }, + }, span: Span { - start: 471, + start: 460, end: 487, }, }, - span: Span { - start: 460, - end: 487, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result5", - span: Span { - start: 488, - end: 495, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result5", span: Span { - start: 499, - end: 504, + start: 488, + end: 495, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "or:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", span: Span { - start: 505, - end: 508, + start: 499, + end: 504, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 510, - end: 514, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 505, + end: 508, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 510, + end: 514, + }, + }, + ), }, - ), - ], - span: Span { - start: 509, - end: 515, + ], + span: Span { + start: 509, + end: 515, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 499, + end: 515, + }, + }, span: Span { - start: 499, + start: 488, end: 515, }, }, - span: Span { - start: 488, - end: 515, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result6", - span: Span { - start: 516, - end: 523, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result6", span: Span { - start: 527, - end: 532, + start: 516, + end: 523, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "or:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", span: Span { - start: 533, - end: 536, + start: 527, + end: 532, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "false", - span: Span { - start: 538, - end: 543, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 533, + end: 536, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "false", + span: Span { + start: 538, + end: 543, + }, + }, + ), }, - ), - ], - span: Span { - start: 537, - end: 544, + ], + span: Span { + start: 537, + end: 544, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 527, + end: 544, + }, + }, span: Span { - start: 527, + start: 516, end: 544, }, }, - span: Span { - start: 516, - end: 544, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result7", - span: Span { - start: 566, - end: 573, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result7", span: Span { - start: 577, - end: 581, + start: 566, + end: 573, }, }, ), - selector: Unary( - "not", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", + span: Span { + start: 577, + end: 581, + }, + }, + ), + selector: Unary( + "not", + ), + arguments: [], + is_cast: false, + span: Span { + start: 577, + end: 585, + }, + }, span: Span { - start: 577, + start: 566, end: 585, }, }, - span: Span { - start: 566, - end: 585, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result8", - span: Span { - start: 586, - end: 593, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result8", span: Span { - start: 597, - end: 602, + start: 586, + end: 593, }, }, ), - selector: Unary( - "not", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", + span: Span { + start: 597, + end: 602, + }, + }, + ), + selector: Unary( + "not", + ), + arguments: [], + is_cast: false, + span: Span { + start: 597, + end: 606, + }, + }, span: Span { - start: 597, + start: 586, end: 606, }, }, - span: Span { - start: 586, - end: 606, - }, }, ], span: Span { start: 154, end: 606, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_dictionary_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_dictionary_parser.snap index a6e3184c0..5a9143189 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_dictionary_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_dictionary_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,1191 +7,1323 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "person", - span: Span { - start: 140, - end: 146, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "person", + span: Span { + start: 140, + end: 146, + }, }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "name", + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "name", + ), + Span { + start: 152, + end: 157, + }, ), - Span { - start: 152, - end: 157, - }, - ), - value: Literal( - String( - "Alice", + value: Literal( + String( + "Alice", + ), + Span { + start: 161, + end: 168, + }, ), - Span { - start: 161, + span: Span { + start: 152, end: 168, }, - ), - span: Span { - start: 152, - end: 168, }, - }, - MapPair { - key: Literal( - Symbol( - "age", + MapPair { + key: Literal( + Symbol( + "age", + ), + Span { + start: 170, + end: 174, + }, ), - Span { - start: 170, - end: 174, - }, - ), - value: Literal( - Integer( - 30, + value: Literal( + Integer( + 30, + ), + Span { + start: 178, + end: 180, + }, ), - Span { - start: 178, + span: Span { + start: 170, end: 180, }, - ), - span: Span { - start: 170, - end: 180, }, - }, - MapPair { - key: Literal( - Symbol( - "city", + MapPair { + key: Literal( + Symbol( + "city", + ), + Span { + start: 182, + end: 187, + }, ), - Span { - start: 182, - end: 187, - }, - ), - value: Literal( - String( - "NYC", + value: Literal( + String( + "NYC", + ), + Span { + start: 191, + end: 196, + }, ), - Span { - start: 191, + span: Span { + start: 182, end: 196, }, - ), - span: Span { - start: 182, - end: 196, }, + ], + span: Span { + start: 150, + end: 197, }, - ], + }, span: Span { - start: 150, + start: 140, end: 197, }, }, - span: Span { - start: 140, - end: 197, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "empty", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "empty", + span: Span { + start: 198, + end: 203, + }, + }, + ), + value: MapLiteral { + pairs: [], span: Span { - start: 198, - end: 203, + start: 207, + end: 210, }, }, - ), - value: MapLiteral { - pairs: [], span: Span { - start: 207, + start: 198, end: 210, }, }, - span: Span { - start: 198, - end: 210, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "name", - span: Span { - start: 226, - end: 230, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "name", span: Span { - start: 234, - end: 240, + start: 226, + end: 230, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 241, - end: 244, + start: 234, + end: 240, }, }, - ], - ), - arguments: [ - Literal( - Symbol( - "name", - ), - Span { - start: 245, - end: 250, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 241, + end: 244, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "name", + ), + Span { + start: 245, + end: 250, + }, + ), + ], + is_cast: false, + span: Span { + start: 234, + end: 250, + }, + }, span: Span { - start: 234, + start: 226, end: 250, }, }, - span: Span { - start: 226, - end: 250, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "age", - span: Span { - start: 251, - end: 254, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "age", span: Span { - start: 258, - end: 264, + start: 251, + end: 254, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 265, - end: 268, + start: 258, + end: 264, }, }, - ], - ), - arguments: [ - Literal( - Symbol( - "age", - ), - Span { - start: 269, - end: 273, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 265, + end: 268, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "age", + ), + Span { + start: 269, + end: 273, + }, + ), + ], + is_cast: false, + span: Span { + start: 258, + end: 273, + }, + }, span: Span { - start: 258, + start: 251, end: 273, }, }, - span: Span { - start: 251, - end: 273, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "title", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "title", + span: Span { + start: 303, + end: 308, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", + span: Span { + start: 312, + end: 318, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 319, + end: 322, + }, + }, + KeywordPart { + keyword: "ifAbsent:", + span: Span { + start: 330, + end: 339, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "title", + ), + Span { + start: 323, + end: 329, + }, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "Unknown", + ), + Span { + start: 341, + end: 350, + }, + ), + }, + ], + span: Span { + start: 340, + end: 351, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 303, - end: 308, + start: 312, + end: 351, }, }, - ), - value: MessageSend { - receiver: Identifier( + span: Span { + start: 303, + end: 351, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "older", span: Span { - start: 312, - end: 318, + start: 388, + end: 393, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 319, - end: 322, + start: 397, + end: 403, }, }, - KeywordPart { - keyword: "ifAbsent:", - span: Span { - start: 330, - end: 339, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 404, + end: 407, + }, }, - }, + KeywordPart { + keyword: "put:", + span: Span { + start: 413, + end: 417, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "age", + ), + Span { + start: 408, + end: 412, + }, + ), + Literal( + Integer( + 31, + ), + Span { + start: 418, + end: 420, + }, + ), ], + is_cast: false, + span: Span { + start: 397, + end: 420, + }, + }, + span: Span { + start: 388, + end: 420, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "withJob", + span: Span { + start: 437, + end: 444, + }, + }, ), - arguments: [ - Literal( - Symbol( - "title", - ), - Span { - start: 323, - end: 329, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", + span: Span { + start: 448, + end: 454, + }, }, ), - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "Unknown", - ), - Span { - start: 341, - end: 350, - }, - ), - ], + selector: Keyword( + [ + KeywordPart { + keyword: "at:", + span: Span { + start: 455, + end: 458, + }, + }, + KeywordPart { + keyword: "put:", + span: Span { + start: 464, + end: 468, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "job", + ), + Span { + start: 459, + end: 463, + }, + ), + Literal( + String( + "Engineer", + ), + Span { + start: 469, + end: 479, + }, + ), + ], + is_cast: false, + span: Span { + start: 448, + end: 479, + }, + }, + span: Span { + start: 437, + end: 479, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "size", + span: Span { + start: 489, + end: 493, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 340, - end: 351, + start: 497, + end: 503, }, }, ), - ], - is_cast: false, + selector: Unary( + "size", + ), + arguments: [], + is_cast: false, + span: Span { + start: 497, + end: 508, + }, + }, span: Span { - start: 312, - end: 351, + start: 489, + end: 508, }, }, - span: Span { - start: 303, - end: 351, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "older", - span: Span { - start: 388, - end: 393, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "hasName", span: Span { - start: 397, - end: 403, + start: 522, + end: 529, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 404, - end: 407, + start: 533, + end: 539, }, }, - KeywordPart { - keyword: "put:", - span: Span { - start: 413, - end: 417, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "includesKey:", + span: Span { + start: 540, + end: 552, + }, }, - }, - ], - ), - arguments: [ - Literal( - Symbol( - "age", - ), - Span { - start: 408, - end: 412, - }, + ], ), - Literal( - Integer( - 31, + arguments: [ + Literal( + Symbol( + "name", + ), + Span { + start: 553, + end: 558, + }, ), - Span { - start: 418, - end: 420, - }, - ), - ], - is_cast: false, + ], + is_cast: false, + span: Span { + start: 533, + end: 558, + }, + }, span: Span { - start: 397, - end: 420, + start: 522, + end: 558, }, }, - span: Span { - start: 388, - end: 420, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "withJob", - span: Span { - start: 437, - end: 444, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "hasJob", span: Span { - start: 448, - end: 454, + start: 559, + end: 565, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "at:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 455, - end: 458, + start: 569, + end: 575, }, }, - KeywordPart { - keyword: "put:", - span: Span { - start: 464, - end: 468, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "includesKey:", + span: Span { + start: 576, + end: 588, + }, }, - }, - ], - ), - arguments: [ - Literal( - Symbol( - "job", - ), - Span { - start: 459, - end: 463, - }, + ], ), - Literal( - String( - "Engineer", + arguments: [ + Literal( + Symbol( + "job", + ), + Span { + start: 589, + end: 593, + }, ), - Span { - start: 469, - end: 479, - }, - ), - ], - is_cast: false, + ], + is_cast: false, + span: Span { + start: 569, + end: 593, + }, + }, span: Span { - start: 448, - end: 479, + start: 559, + end: 593, }, }, - span: Span { - start: 437, - end: 479, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "size", - span: Span { - start: 489, - end: 493, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "minimal", span: Span { - start: 497, - end: 503, + start: 609, + end: 616, }, }, ), - selector: Unary( - "size", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", + span: Span { + start: 620, + end: 626, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "removeKey:", + span: Span { + start: 627, + end: 637, + }, + }, + ], + ), + arguments: [ + Literal( + Symbol( + "city", + ), + Span { + start: 638, + end: 643, + }, + ), + ], + is_cast: false, + span: Span { + start: 620, + end: 643, + }, + }, span: Span { - start: 497, - end: 508, + start: 609, + end: 643, }, }, - span: Span { - start: 489, - end: 508, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "hasName", - span: Span { - start: 522, - end: 529, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "keys", span: Span { - start: 533, - end: 539, + start: 668, + end: 672, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "includesKey:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 540, - end: 552, + start: 676, + end: 682, }, }, - ], - ), - arguments: [ - Literal( - Symbol( - "name", - ), - Span { - start: 553, - end: 558, - }, ), - ], - is_cast: false, + selector: Unary( + "keys", + ), + arguments: [], + is_cast: false, + span: Span { + start: 676, + end: 687, + }, + }, span: Span { - start: 533, - end: 558, + start: 668, + end: 687, }, }, - span: Span { - start: 522, - end: 558, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "hasJob", - span: Span { - start: 559, - end: 565, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "person", + name: "values", span: Span { - start: 569, - end: 575, + start: 688, + end: 694, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "includesKey:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "person", span: Span { - start: 576, - end: 588, + start: 698, + end: 704, }, }, - ], - ), - arguments: [ - Literal( - Symbol( - "job", - ), - Span { - start: 589, - end: 593, - }, ), - ], - is_cast: false, + selector: Unary( + "values", + ), + arguments: [], + is_cast: false, + span: Span { + start: 698, + end: 711, + }, + }, span: Span { - start: 569, - end: 593, + start: 688, + end: 711, }, }, - span: Span { - start: 559, - end: 593, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "minimal", - span: Span { - start: 609, - end: 616, - }, - }, - ), - value: MessageSend { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { receiver: Identifier( Identifier { name: "person", span: Span { - start: 620, - end: 626, + start: 747, + end: 753, }, }, ), selector: Keyword( [ KeywordPart { - keyword: "removeKey:", + keyword: "keysAndValuesDo:", span: Span { - start: 627, - end: 637, + start: 754, + end: 770, }, }, ], ), arguments: [ - Literal( - Symbol( - "city", - ), - Span { - start: 638, - end: 643, + Block( + Block { + parameters: [ + BlockParameter { + name: "k", + span: Span { + start: 773, + end: 774, + }, + }, + BlockParameter { + name: "v", + span: Span { + start: 776, + end: 777, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 782, + end: 792, + }, + }, + span: Span { + start: 782, + end: 792, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 793, + end: 798, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "k", + span: Span { + start: 799, + end: 800, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 782, + end: 800, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Transcript", + span: Span { + start: 803, + end: 813, + }, + }, + span: Span { + start: 803, + end: 813, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "show:", + span: Span { + start: 814, + end: 819, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "v", + span: Span { + start: 820, + end: 821, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 803, + end: 821, + }, + }, + }, + ], + span: Span { + start: 771, + end: 823, + }, }, ), ], is_cast: false, span: Span { - start: 620, - end: 643, + start: 747, + end: 823, }, }, - span: Span { - start: 609, - end: 643, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "keys", - span: Span { - start: 668, - end: 672, - }, - }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "person", - span: Span { - start: 676, - end: 682, - }, - }, - ), - selector: Unary( - "keys", - ), - arguments: [], - is_cast: false, - span: Span { - start: 676, - end: 687, - }, - }, - span: Span { - start: 668, - end: 687, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Assignment { - target: Identifier( - Identifier { - name: "values", - span: Span { - start: 688, - end: 694, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + expression: Assignment { + target: Identifier( Identifier { - name: "person", - span: Span { - start: 698, - end: 704, - }, - }, - ), - selector: Unary( - "values", - ), - arguments: [], - is_cast: false, - span: Span { - start: 698, - end: 711, - }, - }, - span: Span { - start: 688, - end: 711, - }, - }, - MessageSend { - receiver: Identifier( - Identifier { - name: "person", - span: Span { - start: 747, - end: 753, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "keysAndValuesDo:", + name: "doubled", span: Span { - start: 754, - end: 770, + start: 853, + end: 860, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "k", + ), + value: MessageSend { + receiver: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "x", + ), + Span { + start: 866, + end: 868, + }, + ), + value: Literal( + Integer( + 10, + ), + Span { + start: 872, + end: 874, + }, + ), span: Span { - start: 773, - end: 774, + start: 866, + end: 874, }, }, - BlockParameter { - name: "v", + MapPair { + key: Literal( + Symbol( + "y", + ), + Span { + start: 876, + end: 878, + }, + ), + value: Literal( + Integer( + 20, + ), + Span { + start: 882, + end: 884, + }, + ), span: Span { - start: 776, - end: 777, + start: 876, + end: 884, }, }, ], - body: [ - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", - span: Span { - start: 782, - end: 792, - }, - }, - span: Span { - start: 782, - end: 792, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 793, - end: 798, - }, - }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "k", - span: Span { - start: 799, - end: 800, - }, - }, - ), - ], - is_cast: false, + span: Span { + start: 864, + end: 885, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "collect:", span: Span { - start: 782, - end: 800, + start: 886, + end: 894, }, }, - MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Transcript", + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "v", span: Span { - start: 803, - end: 813, + start: 897, + end: 898, }, }, - span: Span { - start: 803, - end: 813, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "show:", - span: Span { - start: 814, - end: 819, - }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ], - ), - arguments: [ - Identifier( - Identifier { - name: "v", + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "v", + span: Span { + start: 901, + end: 902, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 905, + end: 906, + }, + ), + ], + is_cast: false, span: Span { - start: 820, - end: 821, + start: 901, + end: 906, }, }, - ), + }, ], - is_cast: false, span: Span { - start: 803, - end: 821, + start: 895, + end: 907, }, }, - ], - span: Span { - start: 771, - end: 823, - }, + ), + ], + is_cast: false, + span: Span { + start: 864, + end: 907, }, - ), - ], - is_cast: false, - span: Span { - start: 747, - end: 823, + }, + span: Span { + start: 853, + end: 907, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "doubled", - span: Span { - start: 853, - end: 860, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "base", + span: Span { + start: 935, + end: 939, + }, }, - }, - ), - value: MessageSend { - receiver: MapLiteral { + ), + value: MapLiteral { pairs: [ MapPair { key: Literal( Symbol( - "x", + "a", ), Span { - start: 866, - end: 868, + start: 945, + end: 947, }, ), value: Literal( Integer( - 10, + 1, ), Span { - start: 872, - end: 874, + start: 951, + end: 952, }, ), span: Span { - start: 866, - end: 874, + start: 945, + end: 952, }, }, MapPair { key: Literal( Symbol( - "y", + "b", ), Span { - start: 876, - end: 878, + start: 954, + end: 956, }, ), value: Literal( Integer( - 20, + 2, ), Span { - start: 882, - end: 884, + start: 960, + end: 961, }, ), span: Span { - start: 876, - end: 884, + start: 954, + end: 961, }, }, ], span: Span { - start: 864, - end: 885, + start: 943, + end: 962, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "collect:", - span: Span { - start: 886, - end: 894, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "v", - span: Span { - start: 897, - end: 898, - }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "v", - span: Span { - start: 901, - end: 902, - }, - }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 905, - end: 906, - }, - ), - ], - is_cast: false, - span: Span { - start: 901, - end: 906, - }, - }, - ], - span: Span { - start: 895, - end: 907, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 864, - end: 907, + start: 935, + end: 962, }, }, - span: Span { - start: 853, - end: 907, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "base", - span: Span { - start: 935, - end: 939, - }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "a", - ), - Span { - start: 945, - end: 947, - }, - ), - value: Literal( - Integer( - 1, - ), - Span { - start: 951, - end: 952, - }, - ), + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "extra", span: Span { - start: 945, - end: 952, + start: 963, + end: 968, }, }, - MapPair { - key: Literal( - Symbol( - "b", - ), - Span { - start: 954, - end: 956, - }, - ), - value: Literal( - Integer( - 2, + ), + value: MapLiteral { + pairs: [ + MapPair { + key: Literal( + Symbol( + "b", + ), + Span { + start: 974, + end: 976, + }, ), - Span { - start: 960, - end: 961, - }, - ), - span: Span { - start: 954, - end: 961, - }, - }, - ], - span: Span { - start: 943, - end: 962, - }, - }, - span: Span { - start: 935, - end: 962, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "extra", - span: Span { - start: 963, - end: 968, - }, - }, - ), - value: MapLiteral { - pairs: [ - MapPair { - key: Literal( - Symbol( - "b", + value: Literal( + Integer( + 3, + ), + Span { + start: 980, + end: 981, + }, ), - Span { + span: Span { start: 974, - end: 976, - }, - ), - value: Literal( - Integer( - 3, - ), - Span { - start: 980, end: 981, }, - ), - span: Span { - start: 974, - end: 981, }, - }, - MapPair { - key: Literal( - Symbol( - "c", + MapPair { + key: Literal( + Symbol( + "c", + ), + Span { + start: 983, + end: 985, + }, ), - Span { - start: 983, - end: 985, - }, - ), - value: Literal( - Integer( - 4, + value: Literal( + Integer( + 4, + ), + Span { + start: 989, + end: 990, + }, ), - Span { - start: 989, + span: Span { + start: 983, end: 990, }, - ), - span: Span { - start: 983, - end: 990, }, + ], + span: Span { + start: 972, + end: 991, }, - ], + }, span: Span { - start: 972, + start: 963, end: 991, }, }, - span: Span { - start: 963, - end: 991, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "merged", - span: Span { - start: 992, - end: 998, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "base", + name: "merged", span: Span { - start: 1002, - end: 1006, + start: 992, + end: 998, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "merge:", - span: Span { - start: 1007, - end: 1013, - }, - }, - ], - ), - arguments: [ - Identifier( + value: MessageSend { + receiver: Identifier( Identifier { - name: "extra", + name: "base", span: Span { - start: 1014, - end: 1019, + start: 1002, + end: 1006, }, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "merge:", + span: Span { + start: 1007, + end: 1013, + }, + }, + ], + ), + arguments: [ + Identifier( + Identifier { + name: "extra", + span: Span { + start: 1014, + end: 1019, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1002, + end: 1019, + }, + }, span: Span { - start: 1002, + start: 992, end: 1019, }, }, - span: Span { - start: 992, - end: 1019, - }, }, ], span: Span { start: 140, end: 1019, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_integer_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_integer_parser.snap index 42e45b000..a3e000a52 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_integer_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_integer_parser.snap @@ -7,1033 +7,1177 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 133, - end: 136, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 140, - end: 141, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", + span: Span { + start: 133, + end: 136, + }, }, ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 3, + 5, ), Span { - start: 144, - end: 145, + start: 140, + end: 141, }, ), - ], - is_cast: false, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 144, + end: 145, + }, + ), + ], + is_cast: false, + span: Span { + start: 140, + end: 145, + }, + }, span: Span { - start: 140, + start: 133, end: 145, }, }, - span: Span { - start: 133, - end: 145, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "difference", - span: Span { - start: 146, - end: 156, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 160, - end: 162, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "difference", + span: Span { + start: 146, + end: 156, + }, }, ), - selector: Binary( - "-", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 4, + 10, ), Span { - start: 165, - end: 166, + start: 160, + end: 162, }, ), - ], - is_cast: false, + selector: Binary( + "-", + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 165, + end: 166, + }, + ), + ], + is_cast: false, + span: Span { + start: 160, + end: 166, + }, + }, span: Span { - start: 160, + start: 146, end: 166, }, }, - span: Span { - start: 146, - end: 166, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "product", - span: Span { - start: 167, - end: 174, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 6, - ), - Span { - start: 178, - end: 179, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "product", + span: Span { + start: 167, + end: 174, + }, }, ), - selector: Binary( - "*", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 7, + 6, ), Span { - start: 182, - end: 183, + start: 178, + end: 179, }, ), - ], - is_cast: false, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 7, + ), + Span { + start: 182, + end: 183, + }, + ), + ], + is_cast: false, + span: Span { + start: 178, + end: 183, + }, + }, span: Span { - start: 178, + start: 167, end: 183, }, }, - span: Span { - start: 167, - end: 183, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "quotient", - span: Span { - start: 184, - end: 192, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 20, - ), - Span { - start: 196, - end: 198, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "quotient", + span: Span { + start: 184, + end: 192, + }, }, ), - selector: Binary( - "/", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 4, + 20, ), Span { - start: 201, - end: 202, + start: 196, + end: 198, }, ), - ], - is_cast: false, - span: Span { - start: 196, - end: 202, - }, - }, - span: Span { - start: 184, - end: 202, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "intDiv", + selector: Binary( + "/", + ), + arguments: [ + Literal( + Integer( + 4, + ), + Span { + start: 201, + end: 202, + }, + ), + ], + is_cast: false, span: Span { - start: 235, - end: 241, + start: 196, + end: 202, }, }, - ), - value: Literal( - Integer( - 17, - ), - Span { - start: 245, - end: 247, + span: Span { + start: 184, + end: 202, }, - ), - span: Span { - start: 235, - end: 247, }, }, - Assignment { - target: Identifier( - Identifier { - name: "remainder", - span: Span { - start: 253, - end: 262, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "intDiv", + span: Span { + start: 235, + end: 241, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( + ), + value: Literal( Integer( 17, ), Span { - start: 266, - end: 268, + start: 245, + end: 247, }, ), - selector: Binary( - "%", + span: Span { + start: 235, + end: 247, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "remainder", + span: Span { + start: 253, + end: 262, + }, + }, ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 5, + 17, ), Span { - start: 271, - end: 272, + start: 266, + end: 268, }, ), - ], - is_cast: false, + selector: Binary( + "%", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 271, + end: 272, + }, + ), + ], + is_cast: false, + span: Span { + start: 266, + end: 272, + }, + }, span: Span { - start: 266, + start: 253, end: 272, }, }, - span: Span { - start: 253, - end: 272, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isLess", - span: Span { - start: 288, - end: 294, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 3, - ), - Span { - start: 298, - end: 299, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isLess", + span: Span { + start: 288, + end: 294, + }, }, ), - selector: Binary( - "<", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 5, + 3, ), Span { - start: 302, - end: 303, + start: 298, + end: 299, }, ), - ], - is_cast: false, + selector: Binary( + "<", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 302, + end: 303, + }, + ), + ], + is_cast: false, + span: Span { + start: 298, + end: 303, + }, + }, span: Span { - start: 298, + start: 288, end: 303, }, }, - span: Span { - start: 288, - end: 303, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isGreater", - span: Span { - start: 304, - end: 313, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 317, - end: 319, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isGreater", + span: Span { + start: 304, + end: 313, + }, }, ), - selector: Binary( - ">", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( - 5, + 10, ), Span { - start: 322, - end: 323, + start: 317, + end: 319, }, ), - ], - is_cast: false, + selector: Binary( + ">", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 322, + end: 323, + }, + ), + ], + is_cast: false, + span: Span { + start: 317, + end: 323, + }, + }, span: Span { - start: 317, + start: 304, end: 323, }, }, - span: Span { - start: 304, - end: 323, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEqual", - span: Span { - start: 324, - end: 331, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 7, - ), - Span { - start: 335, - end: 336, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEqual", + span: Span { + start: 324, + end: 331, + }, }, ), - selector: Binary( - "=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( Integer( 7, ), Span { - start: 339, - end: 340, + start: 335, + end: 336, }, ), - ], - is_cast: false, + selector: Binary( + "=", + ), + arguments: [ + Literal( + Integer( + 7, + ), + Span { + start: 339, + end: 340, + }, + ), + ], + is_cast: false, + span: Span { + start: 335, + end: 340, + }, + }, span: Span { - start: 335, + start: 324, end: 340, }, }, - span: Span { - start: 324, - end: 340, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 370, - end: 377, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 370, + end: 377, + }, + }, + ), + value: Literal( + Integer( + 0, + ), + Span { + start: 381, + end: 382, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 381, + span: Span { + start: 370, end: 382, }, - ), - span: Span { - start: 370, - end: 382, }, }, - MessageSend { - receiver: Literal( - Integer( - 5, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 383, + end: 384, + }, ), - Span { - start: 383, - end: 384, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "timesRepeat:", - span: Span { - start: 385, - end: 397, + selector: Keyword( + [ + KeywordPart { + keyword: "timesRepeat:", + span: Span { + start: 385, + end: 397, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "counter", - span: Span { - start: 399, - end: 406, - }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "counter", - span: Span { - start: 410, - end: 417, + expression: Assignment { + target: Identifier( + Identifier { + name: "counter", + span: Span { + start: 399, + end: 406, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "counter", + span: Span { + start: 410, + end: 417, + }, + }, + ), + selector: Binary( + "+", ), - Span { - start: 420, + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 420, + end: 421, + }, + ), + ], + is_cast: false, + span: Span { + start: 410, end: 421, }, - ), - ], - is_cast: false, - span: Span { - start: 410, - end: 421, + }, + span: Span { + start: 399, + end: 421, + }, }, }, - span: Span { - start: 399, - end: 421, - }, + ], + span: Span { + start: 398, + end: 422, }, - ], + }, + ), + ], + is_cast: false, + span: Span { + start: 383, + end: 422, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "sum", span: Span { - start: 398, - end: 422, + start: 443, + end: 446, }, }, ), - ], - is_cast: false, - span: Span { - start: 383, - end: 422, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 443, - end: 446, + value: Literal( + Integer( + 0, + ), + Span { + start: 450, + end: 451, }, - }, - ), - value: Literal( - Integer( - 0, ), - Span { - start: 450, + span: Span { + start: 443, end: 451, }, - ), - span: Span { - start: 443, - end: 451, }, }, - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 452, - end: 453, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", - span: Span { - start: 454, - end: 457, - }, - }, - KeywordPart { - keyword: "do:", - span: Span { - start: 461, - end: 464, - }, - }, - ], - ), - arguments: [ - Literal( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( Integer( - 10, + 1, ), Span { - start: 458, - end: 460, + start: 452, + end: 453, }, ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 467, - end: 468, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 454, + end: 457, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "sum", - span: Span { - start: 471, - end: 474, - }, + }, + KeywordPart { + keyword: "do:", + span: Span { + start: 461, + end: 464, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 458, + end: 460, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 467, + end: 468, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "sum", - span: Span { - start: 478, - end: 481, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "n", + name: "sum", span: Span { - start: 484, - end: 485, + start: 471, + end: 474, }, }, ), - ], - is_cast: false, - span: Span { - start: 478, - end: 485, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "sum", + span: Span { + start: 478, + end: 481, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 484, + end: 485, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 478, + end: 485, + }, + }, + span: Span { + start: 471, + end: 485, + }, }, }, - span: Span { - start: 471, - end: 485, - }, + ], + span: Span { + start: 465, + end: 486, }, - ], - span: Span { - start: 465, - end: 486, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 452, - end: 486, + ), + ], + is_cast: false, + span: Span { + start: 452, + end: 486, + }, }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEven", - span: Span { - start: 504, - end: 510, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEven", + span: Span { + start: 504, + end: 510, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 4, + ), + value: MessageSend { + receiver: Literal( + Integer( + 4, + ), + Span { + start: 514, + end: 515, + }, ), - Span { + selector: Unary( + "isEven", + ), + arguments: [], + is_cast: false, + span: Span { start: 514, - end: 515, + end: 522, }, - ), - selector: Unary( - "isEven", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 514, + start: 504, end: 522, }, }, - span: Span { - start: 504, - end: 522, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isOdd", - span: Span { - start: 523, - end: 528, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isOdd", + span: Span { + start: 523, + end: 528, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 7, + ), + value: MessageSend { + receiver: Literal( + Integer( + 7, + ), + Span { + start: 532, + end: 533, + }, ), - Span { + selector: Unary( + "isOdd", + ), + arguments: [], + is_cast: false, + span: Span { start: 532, - end: 533, + end: 539, }, - ), - selector: Unary( - "isOdd", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 532, + start: 523, end: 539, }, }, - span: Span { - start: 523, - end: 539, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isZero", - span: Span { - start: 540, - end: 546, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isZero", + span: Span { + start: 540, + end: 546, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 0, + ), + value: MessageSend { + receiver: Literal( + Integer( + 0, + ), + Span { + start: 550, + end: 551, + }, ), - Span { + selector: Unary( + "isZero", + ), + arguments: [], + is_cast: false, + span: Span { start: 550, - end: 551, + end: 558, }, - ), - selector: Unary( - "isZero", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 550, + start: 540, end: 558, }, }, - span: Span { - start: 540, - end: 558, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "oddSum", - span: Span { - start: 615, - end: 621, - }, - }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 625, - end: 626, - }, - ), - span: Span { - start: 615, - end: 626, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 627, - end: 628, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", + expression: Assignment { + target: Identifier( + Identifier { + name: "oddSum", span: Span { - start: 629, - end: 632, + start: 615, + end: 621, }, }, - KeywordPart { - keyword: "by:", - span: Span { - start: 636, - end: 639, - }, - }, - KeywordPart { - keyword: "do:", - span: Span { - start: 642, - end: 645, - }, - }, - ], - ), - arguments: [ - Literal( + ), + value: Literal( Integer( - 10, + 0, ), Span { - start: 633, - end: 635, + start: 625, + end: 626, }, ), - Literal( + span: Span { + start: 615, + end: 626, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( Integer( - 2, + 1, ), Span { - start: 640, - end: 641, + start: 627, + end: 628, }, ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 648, - end: 649, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 629, + end: 632, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "oddSum", - span: Span { - start: 652, - end: 658, - }, + }, + KeywordPart { + keyword: "by:", + span: Span { + start: 636, + end: 639, + }, + }, + KeywordPart { + keyword: "do:", + span: Span { + start: 642, + end: 645, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 633, + end: 635, + }, + ), + Literal( + Integer( + 2, + ), + Span { + start: 640, + end: 641, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 648, + end: 649, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "oddSum", - span: Span { - start: 662, - end: 668, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "n", + name: "oddSum", span: Span { - start: 671, - end: 672, + start: 652, + end: 658, }, }, ), - ], - is_cast: false, - span: Span { - start: 662, - end: 672, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "oddSum", + span: Span { + start: 662, + end: 668, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "n", + span: Span { + start: 671, + end: 672, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 662, + end: 672, + }, + }, + span: Span { + start: 652, + end: 672, + }, }, }, - span: Span { - start: 652, - end: 672, - }, + ], + span: Span { + start: 646, + end: 673, }, - ], - span: Span { - start: 646, - end: 673, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 627, - end: 673, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "countdown", - span: Span { - start: 728, - end: 737, - }, - }, - ), - value: Literal( - Integer( - 0, - ), - Span { - start: 741, - end: 742, + ), + ], + is_cast: false, + span: Span { + start: 627, + end: 673, }, - ), - span: Span { - start: 728, - end: 742, }, }, - MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 743, - end: 745, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "to:", - span: Span { - start: 746, - end: 749, - }, - }, - KeywordPart { - keyword: "by:", - span: Span { - start: 752, - end: 755, - }, - }, - KeywordPart { - keyword: "do:", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "countdown", span: Span { - start: 759, - end: 762, + start: 728, + end: 737, }, }, - ], - ), - arguments: [ - Literal( + ), + value: Literal( Integer( - 1, + 0, ), Span { - start: 750, - end: 751, + start: 741, + end: 742, }, ), - Literal( + span: Span { + start: 728, + end: 742, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( Integer( - -1, + 10, ), Span { - start: 756, - end: 758, + start: 743, + end: 745, }, ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 765, - end: 766, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "to:", + span: Span { + start: 746, + end: 749, }, - ], - body: [ - Assignment { - target: Identifier( - Identifier { - name: "countdown", - span: Span { - start: 769, - end: 778, - }, + }, + KeywordPart { + keyword: "by:", + span: Span { + start: 752, + end: 755, + }, + }, + KeywordPart { + keyword: "do:", + span: Span { + start: 759, + end: 762, + }, + }, + ], + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 750, + end: 751, + }, + ), + Literal( + Integer( + -1, + ), + Span { + start: 756, + end: 758, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 765, + end: 766, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "countdown", - span: Span { - start: 782, - end: 791, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "countdown", + span: Span { + start: 769, + end: 778, + }, }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "countdown", + span: Span { + start: 782, + end: 791, + }, + }, ), - Span { - start: 794, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 794, + end: 795, + }, + ), + ], + is_cast: false, + span: Span { + start: 782, end: 795, }, - ), - ], - is_cast: false, - span: Span { - start: 782, - end: 795, + }, + span: Span { + start: 769, + end: 795, + }, }, }, - span: Span { - start: 769, - end: 795, - }, + ], + span: Span { + start: 763, + end: 796, }, - ], - span: Span { - start: 763, - end: 796, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 743, - end: 796, + ), + ], + is_cast: false, + span: Span { + start: 743, + end: 796, + }, }, }, ], @@ -1041,7 +1185,7 @@ Module { start: 133, end: 796, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_list_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_list_parser.snap index 3e3c939be..19716a9de 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_list_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_list_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,141 +7,219 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "numbers", - span: Span { - start: 126, - end: 133, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "numbers", + span: Span { + start: 126, + end: 133, + }, }, - }, - ), - value: Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 1, - ), - Span { - start: 138, - end: 139, + ), + value: Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 1, + ), + Span { + start: 138, + end: 139, + }, + ), }, - ), - ], - span: Span { - start: 137, - end: 138, + ], + span: Span { + start: 137, + end: 138, + }, }, + ), + span: Span { + start: 126, + end: 138, }, - ), - span: Span { - start: 126, - end: 138, }, }, - Error { - message: "Unexpected token: expected expression, found ,", - span: Span { - start: 139, - end: 140, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 151, - end: 152, + expression: Error { + message: "Unexpected token: expected expression, found ,", + span: Span { + start: 139, + end: 140, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 163, - end: 164, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 151, + end: 152, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 412, - end: 413, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 163, + end: 164, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 472, - end: 473, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 412, + end: 413, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 528, - end: 529, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 472, + end: 473, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 593, - end: 594, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 528, + end: 529, + }, }, }, - MessageSend { - receiver: Error { + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { message: "Unexpected token: expected expression, found ]", span: Span { - start: 682, - end: 683, + start: 593, + end: 594, }, }, - selector: Binary( - "++", - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 3, - ), - Span { - start: 688, - end: 689, - }, - ), - ], - span: Span { - start: 687, - end: 688, - }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 682, + end: 683, }, + }, + selector: Binary( + "++", ), - ], - is_cast: false, - span: Span { - start: 682, - end: 688, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 3, + ), + Span { + start: 688, + end: 689, + }, + ), + }, + ], + span: Span { + start: 687, + end: 688, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 682, + end: 688, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ,", - span: Span { - start: 689, - end: 690, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ,", + span: Span { + start: 689, + end: 690, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 692, - end: 693, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 692, + end: 693, + }, }, }, ], @@ -150,7 +227,7 @@ Module { start: 126, end: 838, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_object_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_object_parser.snap index 1ddb97927..2b5d52a2a 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_object_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_object_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,1892 +7,2470 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "result1", - span: Span { - start: 653, - end: 660, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result1", + span: Span { + start: 653, + end: 660, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, + ), + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 664, + end: 666, + }, ), - Span { + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 664, - end: 666, + end: 672, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 664, + start: 653, end: 672, }, }, - span: Span { - start: 653, - end: 672, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 691, - end: 698, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result2", + span: Span { + start: 691, + end: 698, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, + ), + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 702, + end: 704, + }, ), - Span { + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 702, - end: 704, + end: 711, }, - ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 702, + start: 691, end: 711, }, }, - span: Span { - start: 691, - end: 711, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result3", - span: Span { - start: 728, - end: 735, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result3", + span: Span { + start: 728, + end: 735, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 0, + ), + value: MessageSend { + receiver: Literal( + Integer( + 0, + ), + Span { + start: 739, + end: 740, + }, ), - Span { + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 739, - end: 740, + end: 746, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 739, + start: 728, end: 746, }, }, - span: Span { - start: 728, - end: 746, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result4", - span: Span { - start: 820, - end: 827, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result4", + span: Span { + start: 820, + end: 827, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", + ), + value: MessageSend { + receiver: Literal( + String( + "hello", + ), + Span { + start: 831, + end: 838, + }, ), - Span { + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 831, - end: 838, + end: 844, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 831, + start: 820, end: 844, }, }, - span: Span { - start: 820, - end: 844, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result5", - span: Span { - start: 859, - end: 866, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result5", + span: Span { + start: 859, + end: 866, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", + ), + value: MessageSend { + receiver: Literal( + String( + "hello", + ), + Span { + start: 870, + end: 877, + }, ), - Span { + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 870, - end: 877, + end: 884, }, - ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 870, + start: 859, end: 884, }, }, - span: Span { - start: 859, - end: 884, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result6", - span: Span { - start: 897, - end: 904, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result6", + span: Span { + start: 897, + end: 904, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "", + ), + value: MessageSend { + receiver: Literal( + String( + "", + ), + Span { + start: 908, + end: 910, + }, ), - Span { + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { start: 908, - end: 910, + end: 916, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 908, + start: 897, end: 916, }, }, - span: Span { - start: 897, - end: 916, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result7", - span: Span { - start: 999, - end: 1006, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result7", span: Span { - start: 1010, - end: 1014, + start: 999, + end: 1006, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", + span: Span { + start: 1010, + end: 1014, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 1010, + end: 1020, + }, + }, span: Span { - start: 1010, + start: 999, end: 1020, }, }, - span: Span { - start: 999, - end: 1020, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result8", - span: Span { - start: 1038, - end: 1045, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "true", + name: "result8", span: Span { - start: 1049, - end: 1053, + start: 1038, + end: 1045, }, }, ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "true", + span: Span { + start: 1049, + end: 1053, + }, + }, + ), + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 1049, + end: 1060, + }, + }, span: Span { - start: 1049, + start: 1038, end: 1060, }, }, - span: Span { - start: 1038, - end: 1060, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result9", - span: Span { - start: 1076, - end: 1083, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result9", span: Span { - start: 1087, - end: 1092, + start: 1076, + end: 1083, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", + span: Span { + start: 1087, + end: 1092, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 1087, + end: 1098, + }, + }, span: Span { - start: 1087, + start: 1076, end: 1098, }, }, - span: Span { - start: 1076, - end: 1098, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result10", - span: Span { - start: 1135, - end: 1143, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "false", + name: "result10", span: Span { - start: 1147, - end: 1152, + start: 1135, + end: 1143, }, }, ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "false", + span: Span { + start: 1147, + end: 1152, + }, + }, + ), + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 1147, + end: 1159, + }, + }, span: Span { - start: 1147, + start: 1135, end: 1159, }, }, - span: Span { - start: 1135, - end: 1159, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result11", - span: Span { - start: 1704, - end: 1712, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, - ), - Span { - start: 1716, - end: 1718, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 1719, - end: 1725, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result11", + span: Span { + start: 1704, + end: 1712, }, - ], + }, ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "default", - ), - Span { - start: 1727, - end: 1736, - }, - ), - ], - span: Span { - start: 1726, - end: 1737, - }, + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 1716, + end: 1718, }, ), - ], - is_cast: false, - span: Span { - start: 1716, - end: 1737, - }, - }, - span: Span { - start: 1704, - end: 1737, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result12", - span: Span { - start: 1809, - end: 1817, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, - ), - Span { - start: 1821, - end: 1823, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 1824, - end: 1833, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 1836, - end: 1839, - }, + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 1719, + end: 1725, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "val", - span: Span { - start: 1842, - end: 1845, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + expression: Literal( + String( + "default", ), Span { - start: 1848, - end: 1849, + start: 1727, + end: 1736, }, ), - ], - is_cast: false, - span: Span { - start: 1842, - end: 1849, }, + ], + span: Span { + start: 1726, + end: 1737, }, - ], - span: Span { - start: 1834, - end: 1850, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1716, + end: 1737, + }, + }, span: Span { - start: 1821, - end: 1850, + start: 1704, + end: 1737, }, }, - span: Span { - start: 1809, - end: 1850, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result13", - span: Span { - start: 1922, - end: 1930, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 1934, - end: 1941, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result12", + span: Span { + start: 1809, + end: 1817, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 1942, - end: 1948, - }, - }, - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 1961, - end: 1970, - }, + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 1821, + end: 1823, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "was nil", - ), - Span { - start: 1950, - end: 1959, - }, - ), - ], - span: Span { - start: 1949, - end: 1960, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 1824, + end: 1833, + }, }, - }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 1973, - end: 1976, + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 1836, + end: 1839, + }, }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "val", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 1842, + end: 1845, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1848, + end: 1849, + }, + ), + ], + is_cast: false, span: Span { - start: 1979, - end: 1982, + start: 1842, + end: 1849, }, }, - ), - selector: Unary( - "uppercase", - ), - arguments: [], - is_cast: false, - span: Span { - start: 1979, - end: 1992, }, + ], + span: Span { + start: 1834, + end: 1850, }, - ], - span: Span { - start: 1971, - end: 1993, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1821, + end: 1850, + }, + }, span: Span { - start: 1934, - end: 1993, + start: 1809, + end: 1850, }, }, - span: Span { - start: 1922, - end: 1993, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result14", - span: Span { - start: 2087, - end: 2095, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 2099, - end: 2101, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result13", + span: Span { + start: 1922, + end: 1930, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 2102, - end: 2111, - }, + value: MessageSend { + receiver: Literal( + String( + "hello", + ), + Span { + start: 1934, + end: 1941, }, - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 2129, - end: 2135, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 1942, + end: 1948, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 2114, - end: 2117, - }, + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 1961, + end: 1970, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "val", - span: Span { - start: 2120, - end: 2123, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, + expression: Literal( + String( + "was nil", ), Span { - start: 2126, - end: 2127, + start: 1950, + end: 1959, }, ), - ], - is_cast: false, - span: Span { - start: 2120, - end: 2127, }, + ], + span: Span { + start: 1949, + end: 1960, }, - ], - span: Span { - start: 2112, - end: 2128, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 2137, - end: 2138, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 1973, + end: 1976, + }, }, - ), - ], - span: Span { - start: 2136, - end: 2139, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 1979, + end: 1982, + }, + }, + ), + selector: Unary( + "uppercase", + ), + arguments: [], + is_cast: false, + span: Span { + start: 1979, + end: 1992, + }, + }, + }, + ], + span: Span { + start: 1971, + end: 1993, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1934, + end: 1993, + }, + }, span: Span { - start: 2099, - end: 2139, + start: 1922, + end: 1993, }, }, - span: Span { - start: 2087, - end: 2139, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result15", - span: Span { - start: 2675, - end: 2683, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 100, - ), - Span { - start: 2687, - end: 2690, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result14", + span: Span { + start: 2087, + end: 2095, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 2691, - end: 2700, - }, + value: MessageSend { + receiver: Literal( + Integer( + 10, + ), + Span { + start: 2099, + end: 2101, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 2703, - end: 2704, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 2102, + end: 2111, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", + }, + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 2129, + end: 2135, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 2114, + end: 2117, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 2120, + end: 2123, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 2126, + end: 2127, + }, + ), + ], + is_cast: false, span: Span { - start: 2707, - end: 2708, + start: 2120, + end: 2127, }, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( + }, + ], + span: Span { + start: 2112, + end: 2128, + }, + }, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( Integer( - 50, + 0, ), Span { - start: 2711, - end: 2713, + start: 2137, + end: 2138, }, ), - ], - is_cast: false, - span: Span { - start: 2707, - end: 2713, }, + ], + span: Span { + start: 2136, + end: 2139, }, - ], - span: Span { - start: 2701, - end: 2714, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 2099, + end: 2139, + }, + }, span: Span { - start: 2687, - end: 2714, + start: 2087, + end: 2139, }, }, - span: Span { - start: 2675, - end: 2714, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result16", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result15", + span: Span { + start: 2675, + end: 2683, + }, + }, + ), + value: MessageSend { + receiver: Literal( + Integer( + 100, + ), + Span { + start: 2687, + end: 2690, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 2691, + end: 2700, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 2703, + end: 2704, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 2707, + end: 2708, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 50, + ), + Span { + start: 2711, + end: 2713, + }, + ), + ], + is_cast: false, + span: Span { + start: 2707, + end: 2713, + }, + }, + }, + ], + span: Span { + start: 2701, + end: 2714, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 2726, - end: 2734, + start: 2687, + end: 2714, }, }, - ), - value: MessageSend { - receiver: Literal( - String( - "test", - ), - Span { - start: 2738, - end: 2744, + span: Span { + start: 2675, + end: 2714, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result16", + span: Span { + start: 2726, + end: 2734, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 2745, - end: 2754, - }, + value: MessageSend { + receiver: Literal( + String( + "test", + ), + Span { + start: 2738, + end: 2744, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "str", - span: Span { - start: 2757, - end: 2760, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 2745, + end: 2754, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "str", + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "str", + span: Span { + start: 2757, + end: 2760, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "str", + span: Span { + start: 2763, + end: 2766, + }, + }, + ), + selector: Unary( + "size", + ), + arguments: [], + is_cast: false, span: Span { start: 2763, - end: 2766, + end: 2771, }, }, - ), - selector: Unary( - "size", - ), - arguments: [], - is_cast: false, - span: Span { - start: 2763, - end: 2771, }, + ], + span: Span { + start: 2755, + end: 2772, }, - ], - span: Span { - start: 2755, - end: 2772, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 2738, + end: 2772, + }, + }, span: Span { - start: 2738, + start: 2726, end: 2772, }, }, - span: Span { - start: 2726, - end: 2772, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result17", - span: Span { - start: 2826, - end: 2834, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result17", + span: Span { + start: 2826, + end: 2834, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 5, + ), + value: MessageSend { + receiver: Literal( + Integer( + 5, + ), + Span { + start: 2838, + end: 2839, + }, ), - Span { + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 2840, + end: 2849, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 2852, + end: 2853, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 2857, + end: 2858, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 2861, + end: 2862, + }, + ), + ], + is_cast: false, + span: Span { + start: 2857, + end: 2862, + }, + }, + span: Span { + start: 2856, + end: 2863, + }, + }, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 2866, + end: 2867, + }, + ), + ], + is_cast: false, + span: Span { + start: 2856, + end: 2867, + }, + }, + }, + ], + span: Span { + start: 2850, + end: 2868, + }, + }, + ), + ], + is_cast: false, + span: Span { start: 2838, - end: 2839, + end: 2868, + }, + }, + span: Span { + start: 2826, + end: 2868, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result18", + span: Span { + start: 3408, + end: 3416, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 3421, + end: 3423, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 3424, + end: 3433, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "v", + span: Span { + start: 3436, + end: 3437, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "v", + span: Span { + start: 3440, + end: 3441, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 3444, + end: 3445, + }, + ), + ], + is_cast: false, + span: Span { + start: 3440, + end: 3445, + }, + }, + }, + ], + span: Span { + start: 3434, + end: 3446, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 2840, - end: 2849, + start: 3421, + end: 3446, }, }, + span: Span { + start: 3420, + end: 3447, + }, + }, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 3450, + end: 3452, + }, + ), ], + is_cast: false, + span: Span { + start: 3420, + end: 3452, + }, + }, + span: Span { + start: 3408, + end: 3452, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result19", + span: Span { + start: 3500, + end: 3508, + }, + }, ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 2852, - end: 2853, - }, + value: MessageSend { + receiver: Literal( + Integer( + 10, + ), + Span { + start: 3512, + end: 3514, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 3515, + end: 3524, }, - ], - body: [ - MessageSend { - receiver: Parenthesized { + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "outer", + span: Span { + start: 3527, + end: 3532, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, expression: MessageSend { receiver: Identifier( Identifier { - name: "n", + name: "outer", span: Span { - start: 2857, - end: 2858, + start: 3535, + end: 3540, }, }, ), - selector: Binary( - "*", + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 3541, + end: 3550, + }, + }, + ], ), arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 2861, - end: 2862, + Block( + Block { + parameters: [ + BlockParameter { + name: "inner", + span: Span { + start: 3553, + end: 3558, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "inner", + span: Span { + start: 3561, + end: 3566, + }, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 3569, + end: 3570, + }, + ), + ], + is_cast: false, + span: Span { + start: 3561, + end: 3570, + }, + }, + }, + ], + span: Span { + start: 3551, + end: 3571, + }, }, ), ], is_cast: false, span: Span { - start: 2857, - end: 2862, + start: 3535, + end: 3571, }, }, + }, + ], + span: Span { + start: 3525, + end: 3572, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 3512, + end: 3572, + }, + }, + span: Span { + start: 3500, + end: 3572, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result20", + span: Span { + start: 3629, + end: 3637, + }, + }, + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Literal( + Integer( + 100, + ), + Span { + start: 3642, + end: 3645, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", span: Span { - start: 2856, - end: 2863, + start: 3646, + end: 3652, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 3, - ), - Span { - start: 2866, - end: 2867, - }, - ), - ], - is_cast: false, - span: Span { - start: 2856, - end: 2867, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 0, + ), + Span { + start: 3654, + end: 3655, + }, + ), + }, + ], + span: Span { + start: 3653, + end: 3656, + }, }, - }, + ), ], + is_cast: false, span: Span { - start: 2850, - end: 2868, + start: 3642, + end: 3656, }, }, + span: Span { + start: 3641, + end: 3657, + }, + }, + selector: Binary( + "+", ), - ], - is_cast: false, + arguments: [ + Literal( + Integer( + 50, + ), + Span { + start: 3660, + end: 3662, + }, + ), + ], + is_cast: false, + span: Span { + start: 3641, + end: 3662, + }, + }, span: Span { - start: 2838, - end: 2868, + start: 3629, + end: 3662, }, }, - span: Span { - start: 2826, - end: 2868, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result18", - span: Span { - start: 3408, - end: 3416, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result21", + span: Span { + start: 4190, + end: 4198, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { + ), + value: MessageSend { + receiver: MessageSend { receiver: Literal( Integer( 42, ), Span { - start: 3421, - end: 3423, + start: 4202, + end: 4204, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 3424, - end: 3433, - }, - }, - ], + selector: Unary( + "notNil", ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "v", - span: Span { - start: 3436, - end: 3437, - }, + arguments: [], + is_cast: false, + span: Span { + start: 4202, + end: 4211, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 4212, + end: 4216, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "v", - span: Span { - start: 3440, - end: 3441, - }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 4218, + end: 4222, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 2, - ), - Span { - start: 3444, - end: 3445, - }, - ), - ], - is_cast: false, - span: Span { - start: 3440, - end: 3445, }, - }, - ], - span: Span { - start: 3434, - end: 3446, + ), }, + ], + span: Span { + start: 4217, + end: 4223, }, - ), - ], - is_cast: false, - span: Span { - start: 3421, - end: 3446, - }, - }, + }, + ), + ], + is_cast: false, span: Span { - start: 3420, - end: 3447, + start: 4202, + end: 4223, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 10, - ), - Span { - start: 3450, - end: 3452, - }, - ), - ], - is_cast: false, span: Span { - start: 3420, - end: 3452, + start: 4190, + end: 4223, }, }, - span: Span { - start: 3408, - end: 3452, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result19", - span: Span { - start: 3500, - end: 3508, - }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 10, - ), - Span { - start: 3512, - end: 3514, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result22", + span: Span { + start: 4237, + end: 4245, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 3515, - end: 3524, + value: MessageSend { + receiver: MessageSend { + receiver: Literal( + String( + "test", + ), + Span { + start: 4249, + end: 4255, }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4249, + end: 4261, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "outer", - span: Span { - start: 3527, - end: 3532, - }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 4262, + end: 4265, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "outer", - span: Span { - start: 3535, - end: 3540, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 3541, - end: 3550, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "inner", - span: Span { - start: 3553, - end: 3558, - }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "inner", - span: Span { - start: 3561, - end: 3566, - }, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 3569, - end: 3570, - }, - ), - ], - is_cast: false, - span: Span { - start: 3561, - end: 3570, - }, - }, - ], + expression: Identifier( + Identifier { + name: "false", span: Span { - start: 3551, - end: 3571, + start: 4267, + end: 4272, }, }, ), - ], - is_cast: false, - span: Span { - start: 3535, - end: 3571, }, + ], + span: Span { + start: 4266, + end: 4273, }, - ], - span: Span { - start: 3525, - end: 3572, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 4249, + end: 4273, + }, + }, span: Span { - start: 3512, - end: 3572, + start: 4237, + end: 4273, }, }, - span: Span { - start: 3500, - end: 3572, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result20", - span: Span { - start: 3629, - end: 3637, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result23", + span: Span { + start: 4330, + end: 4338, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { + ), + value: MessageSend { + receiver: MessageSend { receiver: Literal( Integer( 100, ), Span { - start: 3642, - end: 3645, + start: 4342, + end: 4345, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 3646, - end: 3652, + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4342, + end: 4352, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 4353, + end: 4360, + }, + }, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 4376, + end: 4384, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "is not nil", + ), + Span { + start: 4362, + end: 4374, + }, + ), }, + ], + span: Span { + start: 4361, + end: 4375, }, - ], + }, ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "is nil", ), Span { - start: 3654, - end: 3655, + start: 4386, + end: 4394, }, ), - ], - span: Span { - start: 3653, - end: 3656, }, + ], + span: Span { + start: 4385, + end: 4395, }, - ), - ], - is_cast: false, - span: Span { - start: 3642, - end: 3656, - }, - }, - span: Span { - start: 3641, - end: 3657, - }, - }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 50, - ), - Span { - start: 3660, - end: 3662, - }, - ), - ], - is_cast: false, - span: Span { - start: 3641, - end: 3662, - }, - }, - span: Span { - start: 3629, - end: 3662, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result21", - span: Span { - start: 4190, - end: 4198, - }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Literal( - Integer( - 42, + }, ), - Span { - start: 4202, - end: 4204, - }, - ), - selector: Unary( - "notNil", - ), - arguments: [], + ], is_cast: false, span: Span { - start: 4202, - end: 4211, + start: 4342, + end: 4395, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "and:", - span: Span { - start: 4212, - end: 4216, - }, + span: Span { + start: 4330, + end: 4395, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result24", + span: Span { + start: 4912, + end: 4920, }, - ], + }, ), - arguments: [ - Block( + value: MessageSend { + receiver: Block( Block { parameters: [], body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 4218, - end: 4222, - }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: Literal( + Integer( + 42, + ), + Span { + start: 4925, + end: 4927, + }, + ), + }, ], span: Span { - start: 4217, - end: 4223, + start: 4924, + end: 4928, }, }, ), - ], - is_cast: false, - span: Span { - start: 4202, - end: 4223, - }, - }, - span: Span { - start: 4190, - end: 4223, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result22", - span: Span { - start: 4237, - end: 4245, - }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Literal( - String( - "test", - ), - Span { - start: 4249, - end: 4255, - }, - ), selector: Unary( "isNil", ), arguments: [], is_cast: false, span: Span { - start: 4249, - end: 4261, + start: 4924, + end: 4934, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "or:", - span: Span { - start: 4262, - end: 4265, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "false", - span: Span { - start: 4267, - end: 4272, - }, - }, - ), - ], - span: Span { - start: 4266, - end: 4273, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 4249, - end: 4273, + start: 4912, + end: 4934, }, }, - span: Span { - start: 4237, - end: 4273, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result23", - span: Span { - start: 4330, - end: 4338, - }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Literal( - Integer( - 100, - ), - Span { - start: 4342, - end: 4345, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result25", + span: Span { + start: 4953, + end: 4961, }, - ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, - span: Span { - start: 4342, - end: 4352, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 4353, - end: 4360, - }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 4376, - end: 4384, - }, - }, - ], ), - arguments: [ - Block( + value: MessageSend { + receiver: Block( Block { - parameters: [], - body: [ - Literal( - String( - "is not nil", - ), - Span { - start: 4362, - end: 4374, + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 4967, + end: 4968, }, - ), + }, ], - span: Span { - start: 4361, - end: 4375, - }, - }, - ), - Block( - Block { - parameters: [], body: [ - Literal( - String( - "is nil", - ), - Span { - start: 4386, - end: 4394, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), + expression: Identifier( + Identifier { + name: "x", + span: Span { + start: 4971, + end: 4972, + }, + }, + ), + }, ], span: Span { - start: 4385, - end: 4395, + start: 4965, + end: 4973, }, }, ), - ], - is_cast: false, + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4965, + end: 4979, + }, + }, span: Span { - start: 4342, - end: 4395, + start: 4953, + end: 4979, }, }, - span: Span { - start: 4330, - end: 4395, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result24", - span: Span { - start: 4912, - end: 4920, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result26", + span: Span { + start: 5547, + end: 5555, + }, }, - }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [], - body: [ - Literal( + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Literal( Integer( 42, ), Span { - start: 4925, - end: 4927, + start: 5560, + end: 5562, }, ), - ], + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 5563, + end: 5569, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 9999, + ), + Span { + start: 5571, + end: 5575, + }, + ), + }, + ], + span: Span { + start: 5570, + end: 5576, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 5560, + end: 5576, + }, + }, span: Span { - start: 4924, - end: 4928, + start: 5559, + end: 5577, }, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + Integer( + 42, + ), + Span { + start: 5582, + end: 5584, + }, + ), + ], + is_cast: false, + span: Span { + start: 5559, + end: 5584, + }, + }, span: Span { - start: 4924, - end: 4934, + start: 5547, + end: 5584, }, }, - span: Span { - start: 4912, - end: 4934, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result25", - span: Span { - start: 4953, - end: 4961, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result27", + span: Span { + start: 5660, + end: 5668, + }, }, - }, - ), - value: MessageSend { - receiver: Block( - Block { - parameters: [ - BlockParameter { - name: "x", + ), + value: MessageSend { + receiver: Literal( + Integer( + 10, + ), + Span { + start: 5672, + end: 5674, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", span: Span { - start: 4967, - end: 4968, + start: 5675, + end: 5681, }, }, ], - body: [ - Identifier( - Identifier { - name: "x", - span: Span { - start: 4971, - end: 4972, + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Literal( + Integer( + 1, + ), + Span { + start: 5683, + end: 5684, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + MessageSend { + receiver: Literal( + Integer( + 2, + ), + Span { + start: 5687, + end: 5688, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 5691, + end: 5692, + }, + ), + ], + is_cast: false, + span: Span { + start: 5687, + end: 5692, + }, + }, + ], + is_cast: false, + span: Span { + start: 5683, + end: 5692, + }, + }, }, + ], + span: Span { + start: 5682, + end: 5693, }, - ), - ], + }, + ), + ], + is_cast: false, + span: Span { + start: 5672, + end: 5693, + }, + }, + span: Span { + start: 5660, + end: 5693, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "value", span: Span { - start: 4965, - end: 4973, + start: 6236, + end: 6241, }, }, ), - selector: Unary( - "isNil", + value: Literal( + Integer( + 42, + ), + Span { + start: 6245, + end: 6247, + }, ), - arguments: [], - is_cast: false, span: Span { - start: 4965, - end: 4979, + start: 6236, + end: 6247, }, }, - span: Span { - start: 4953, - end: 4979, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result26", - span: Span { - start: 5547, - end: 5555, - }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Literal( - Integer( - 42, - ), - Span { - start: 5560, - end: 5562, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result28", + span: Span { + start: 6248, + end: 6256, + }, + }, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "value", + span: Span { + start: 6260, + end: 6265, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 5563, - end: 5569, - }, - }, - ], + selector: Unary( + "isNil", ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( + arguments: [], + is_cast: false, + span: Span { + start: 6260, + end: 6271, + }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 6272, + end: 6279, + }, + }, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 6284, + end: 6292, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( Integer( - 9999, + 0, ), Span { - start: 5571, - end: 5575, + start: 6281, + end: 6282, }, ), - ], - span: Span { - start: 5570, - end: 5576, }, + ], + span: Span { + start: 6280, + end: 6283, }, - ), - ], - is_cast: false, - span: Span { - start: 5560, - end: 5576, - }, - }, + }, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "value", + span: Span { + start: 6294, + end: 6299, + }, + }, + ), + }, + ], + span: Span { + start: 6293, + end: 6300, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 5559, - end: 5577, + start: 6260, + end: 6300, }, }, - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 42, - ), - Span { - start: 5582, - end: 5584, - }, - ), - ], - is_cast: false, span: Span { - start: 5559, - end: 5584, + start: 6248, + end: 6300, }, }, - span: Span { - start: 5547, - end: 5584, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result27", - span: Span { - start: 5660, - end: 5668, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "value2", + span: Span { + start: 6349, + end: 6355, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( + ), + value: Literal( Integer( 10, ), Span { - start: 5672, - end: 5674, + start: 6359, + end: 6361, + }, + ), + span: Span { + start: 6349, + end: 6361, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result29", + span: Span { + start: 6362, + end: 6370, + }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "value2", span: Span { - start: 5675, - end: 5681, + start: 6374, + end: 6380, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 5683, - end: 5684, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 6381, + end: 6390, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "v", + span: Span { + start: 6393, + end: 6394, }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 2, - ), - Span { - start: 5687, - end: 5688, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "v", + span: Span { + start: 6397, + end: 6398, + }, }, ), selector: Binary( @@ -1905,1071 +2482,943 @@ Module { 3, ), Span { - start: 5691, - end: 5692, + start: 6401, + end: 6402, }, ), ], is_cast: false, span: Span { - start: 5687, - end: 5692, + start: 6397, + end: 6402, }, }, - ], - is_cast: false, - span: Span { - start: 5683, - end: 5692, }, + ], + span: Span { + start: 6391, + end: 6403, }, - ], - span: Span { - start: 5682, - end: 5693, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 5672, - end: 5693, - }, - }, - span: Span { - start: 5660, - end: 5693, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "value", + ), + ], + is_cast: false, span: Span { - start: 6236, - end: 6241, + start: 6374, + end: 6403, }, }, - ), - value: Literal( - Integer( - 42, - ), - Span { - start: 6245, - end: 6247, + span: Span { + start: 6362, + end: 6403, }, - ), - span: Span { - start: 6236, - end: 6247, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result28", - span: Span { - start: 6248, - end: 6256, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result30", + span: Span { + start: 6461, + end: 6469, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { + ), + value: MessageSend { receiver: Identifier( Identifier { - name: "value", + name: "nil", span: Span { - start: 6260, - end: 6265, + start: 6473, + end: 6476, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, - span: Span { - start: 6260, - end: 6271, - }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 6272, - end: 6279, + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 6477, + end: 6483, + }, }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 6284, - end: 6292, + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 6497, + end: 6506, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 6281, - end: 6282, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "nil case", + ), + Span { + start: 6485, + end: 6495, + }, + ), }, - ), - ], - span: Span { - start: 6280, - end: 6283, + ], + span: Span { + start: 6484, + end: 6496, + }, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "value", + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "v", span: Span { - start: 6294, - end: 6299, + start: 6509, + end: 6510, }, }, - ), - ], - span: Span { - start: 6293, - end: 6300, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "not nil case", + ), + Span { + start: 6513, + end: 6527, + }, + ), + }, + ], + span: Span { + start: 6507, + end: 6528, + }, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 6260, - end: 6300, - }, - }, - span: Span { - start: 6248, - end: 6300, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "value2", + ), + ], + is_cast: false, span: Span { - start: 6349, - end: 6355, + start: 6473, + end: 6528, }, }, - ), - value: Literal( - Integer( - 10, - ), - Span { - start: 6359, - end: 6361, + span: Span { + start: 6461, + end: 6528, }, - ), - span: Span { - start: 6349, - end: 6361, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result29", - span: Span { - start: 6362, - end: 6370, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "value2", + name: "result31", span: Span { - start: 6374, - end: 6380, + start: 6547, + end: 6555, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 6381, - end: 6390, - }, + value: MessageSend { + receiver: Literal( + Integer( + 42, + ), + Span { + start: 6559, + end: 6561, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "v", - span: Span { - start: 6393, - end: 6394, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 6562, + end: 6568, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "v", - span: Span { - start: 6397, - end: 6398, + }, + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 6582, + end: 6591, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "nil case", + ), + Span { + start: 6570, + end: 6580, }, + ), + }, + ], + span: Span { + start: 6569, + end: 6581, + }, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "v", + span: Span { + start: 6594, + end: 6595, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( - Integer( - 3, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "not nil case", ), Span { - start: 6401, - end: 6402, + start: 6598, + end: 6612, }, ), - ], - is_cast: false, - span: Span { - start: 6397, - end: 6402, }, + ], + span: Span { + start: 6592, + end: 6613, }, - ], - span: Span { - start: 6391, - end: 6403, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 6559, + end: 6613, + }, + }, span: Span { - start: 6374, - end: 6403, + start: 6547, + end: 6613, }, }, - span: Span { - start: 6362, - end: 6403, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result30", - span: Span { - start: 6461, - end: 6469, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result32", span: Span { - start: 6473, - end: 6476, + start: 7148, + end: 7156, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 6477, - end: 6483, - }, - }, - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 6497, - end: 6506, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "nil case", - ), - Span { - start: 6485, - end: 6495, - }, + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Literal( + Integer( + 5, ), - ], - span: Span { - start: 6484, - end: 6496, - }, - }, - ), - Block( - Block { - parameters: [ - BlockParameter { - name: "v", - span: Span { - start: 6509, - end: 6510, - }, + Span { + start: 7161, + end: 7162, }, - ], - body: [ - Literal( - String( - "not nil case", - ), - Span { - start: 6513, - end: 6527, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 7163, + end: 7172, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "x", + span: Span { + start: 7175, + end: 7176, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "x", + span: Span { + start: 7179, + end: 7180, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 10, + ), + Span { + start: 7183, + end: 7185, + }, + ), + ], + is_cast: false, + span: Span { + start: 7179, + end: 7185, + }, + }, + }, + ], + span: Span { + start: 7173, + end: 7186, + }, }, ), ], + is_cast: false, span: Span { - start: 6507, - end: 6528, + start: 7161, + end: 7186, }, }, - ), - ], - is_cast: false, - span: Span { - start: 6473, - end: 6528, - }, - }, - span: Span { - start: 6461, - end: 6528, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result31", - span: Span { - start: 6547, - end: 6555, + span: Span { + start: 7160, + end: 7187, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - Integer( - 42, + selector: Binary( + "=:=", ), - Span { - start: 6559, - end: 6561, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 6562, - end: 6568, - }, - }, - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 6582, - end: 6591, + arguments: [ + Literal( + Integer( + 50, + ), + Span { + start: 7192, + end: 7194, }, - }, + ), ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "nil case", - ), - Span { - start: 6570, - end: 6580, - }, - ), - ], - span: Span { - start: 6569, - end: 6581, - }, - }, - ), - Block( - Block { - parameters: [ - BlockParameter { - name: "v", - span: Span { - start: 6594, - end: 6595, - }, - }, - ], - body: [ - Literal( - String( - "not nil case", - ), - Span { - start: 6598, - end: 6612, - }, - ), - ], - span: Span { - start: 6592, - end: 6613, - }, - }, - ), - ], - is_cast: false, + is_cast: false, + span: Span { + start: 7160, + end: 7194, + }, + }, span: Span { - start: 6559, - end: 6613, + start: 7148, + end: 7194, }, }, - span: Span { - start: 6547, - end: 6613, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result32", - span: Span { - start: 7148, - end: 7156, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result33", + span: Span { + start: 7241, + end: 7249, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Literal( - Integer( - 5, - ), - Span { - start: 7161, - end: 7162, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 7163, - end: 7172, - }, + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Literal( + Integer( + 100, + ), + Span { + start: 7254, + end: 7257, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "x", - span: Span { - start: 7175, - end: 7176, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 7258, + end: 7264, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "x", - span: Span { - start: 7179, - end: 7180, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( + expression: Literal( Integer( - 10, + 0, ), Span { - start: 7183, - end: 7185, + start: 7266, + end: 7267, }, ), - ], - is_cast: false, - span: Span { - start: 7179, - end: 7185, }, + ], + span: Span { + start: 7265, + end: 7268, }, - ], - span: Span { - start: 7173, - end: 7186, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 7254, + end: 7268, + }, + }, span: Span { - start: 7161, - end: 7186, + start: 7253, + end: 7269, }, }, - span: Span { - start: 7160, - end: 7187, - }, - }, - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 50, - ), - Span { - start: 7192, - end: 7194, - }, + selector: Binary( + "=:=", ), - ], - is_cast: false, - span: Span { - start: 7160, - end: 7194, - }, - }, - span: Span { - start: 7148, - end: 7194, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result33", - span: Span { - start: 7241, - end: 7249, - }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Literal( + arguments: [ + Literal( Integer( 100, ), Span { - start: 7254, - end: 7257, + start: 7274, + end: 7277, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 7258, - end: 7264, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 7266, - end: 7267, - }, - ), - ], - span: Span { - start: 7265, - end: 7268, - }, - }, - ), - ], - is_cast: false, - span: Span { - start: 7254, - end: 7268, - }, - }, + ], + is_cast: false, span: Span { start: 7253, - end: 7269, + end: 7277, }, - }, - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 100, - ), - Span { - start: 7274, - end: 7277, - }, - ), - ], - is_cast: false, + }, span: Span { - start: 7253, + start: 7241, end: 7277, }, }, - span: Span { - start: 7241, - end: 7277, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "userName", - span: Span { - start: 7793, - end: 7801, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "userName", + span: Span { + start: 7793, + end: 7801, + }, + }, + ), + value: Literal( + String( + "Alice", + ), + Span { + start: 7805, + end: 7812, }, - }, - ), - value: Literal( - String( - "Alice", ), - Span { - start: 7805, + span: Span { + start: 7793, end: 7812, }, - ), - span: Span { - start: 7793, - end: 7812, }, }, - Assignment { - target: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 7813, - end: 7821, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "userName", + name: "greeting", span: Span { - start: 7825, - end: 7833, + start: 7813, + end: 7821, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "userName", span: Span { - start: 7834, - end: 7843, + start: 7825, + end: 7833, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "name", - span: Span { - start: 7846, - end: 7850, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 7834, + end: 7843, }, - ], - body: [ - MessageSend { - receiver: MessageSend { - receiver: Literal( - String( - "Hello, ", - ), - Span { - start: 7853, - end: 7862, - }, - ), - selector: Binary( - "+", - ), - arguments: [ - Identifier( - Identifier { - name: "name", - span: Span { - start: 7865, - end: 7869, - }, - }, - ), - ], - is_cast: false, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "name", span: Span { - start: 7853, - end: 7869, + start: 7846, + end: 7850, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - String( - "!", + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: MessageSend { + receiver: Literal( + String( + "Hello, ", + ), + Span { + start: 7853, + end: 7862, + }, + ), + selector: Binary( + "+", + ), + arguments: [ + Identifier( + Identifier { + name: "name", + span: Span { + start: 7865, + end: 7869, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 7853, + end: 7869, + }, + }, + selector: Binary( + "+", ), - Span { - start: 7872, + arguments: [ + Literal( + String( + "!", + ), + Span { + start: 7872, + end: 7875, + }, + ), + ], + is_cast: false, + span: Span { + start: 7853, end: 7875, }, - ), - ], - is_cast: false, - span: Span { - start: 7853, - end: 7875, + }, }, + ], + span: Span { + start: 7844, + end: 7876, }, - ], - span: Span { - start: 7844, - end: 7876, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 7825, + end: 7876, + }, + }, span: Span { - start: 7825, + start: 7813, end: 7876, }, }, - span: Span { - start: 7813, - end: 7876, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "userInput", - span: Span { - start: 7938, - end: 7947, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "userInput", + span: Span { + start: 7938, + end: 7947, + }, + }, + ), + value: Literal( + Integer( + 42, + ), + Span { + start: 7951, + end: 7953, }, - }, - ), - value: Literal( - Integer( - 42, ), - Span { - start: 7951, + span: Span { + start: 7938, end: 7953, }, - ), - span: Span { - start: 7938, - end: 7953, }, }, - Assignment { - target: Identifier( - Identifier { - name: "processedValue", - span: Span { - start: 7954, - end: 7968, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "userInput", + name: "processedValue", span: Span { - start: 7972, - end: 7981, + start: 7954, + end: 7968, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "userInput", span: Span { - start: 7982, - end: 7988, + start: 7972, + end: 7981, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 7990, - end: 7991, - }, - ), - ], - span: Span { - start: 7989, - end: 7992, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 7982, + end: 7988, + }, }, - }, + ], ), - ], - is_cast: false, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 0, + ), + Span { + start: 7990, + end: 7991, + }, + ), + }, + ], + span: Span { + start: 7989, + end: 7992, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 7972, + end: 7992, + }, + }, span: Span { - start: 7972, + start: 7954, end: 7992, }, }, - span: Span { - start: 7954, - end: 7992, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "maybeNumber", - span: Span { - start: 8043, - end: 8054, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "maybeNumber", + span: Span { + start: 8043, + end: 8054, + }, + }, + ), + value: Literal( + Integer( + 7, + ), + Span { + start: 8058, + end: 8059, }, - }, - ), - value: Literal( - Integer( - 7, ), - Span { - start: 8058, + span: Span { + start: 8043, end: 8059, }, - ), - span: Span { - start: 8043, - end: 8059, }, }, - Assignment { - target: Identifier( - Identifier { - name: "doubled", - span: Span { - start: 8060, - end: 8067, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "maybeNumber", + name: "doubled", span: Span { - start: 8071, - end: 8082, + start: 8060, + end: 8067, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "maybeNumber", span: Span { - start: 8083, - end: 8089, + start: 8071, + end: 8082, }, }, - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 8094, - end: 8103, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 8083, + end: 8089, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 0, - ), - Span { - start: 8091, - end: 8092, - }, - ), - ], - span: Span { - start: 8090, - end: 8093, + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 8094, + end: 8103, + }, }, - }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "n", - span: Span { - start: 8106, - end: 8107, - }, - }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "n", - span: Span { - start: 8110, - end: 8111, - }, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "*", - ), - arguments: [ - Literal( + expression: Literal( Integer( - 2, + 0, ), Span { - start: 8114, - end: 8115, + start: 8091, + end: 8092, }, ), - ], - is_cast: false, - span: Span { - start: 8110, - end: 8115, }, + ], + span: Span { + start: 8090, + end: 8093, }, - ], - span: Span { - start: 8104, - end: 8116, }, - }, - ), - ], - is_cast: false, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "n", + span: Span { + start: 8106, + end: 8107, + }, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "n", + span: Span { + start: 8110, + end: 8111, + }, + }, + ), + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 8114, + end: 8115, + }, + ), + ], + is_cast: false, + span: Span { + start: 8110, + end: 8115, + }, + }, + }, + ], + span: Span { + start: 8104, + end: 8116, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 8071, + end: 8116, + }, + }, span: Span { - start: 8071, + start: 8060, end: 8116, }, }, - span: Span { - start: 8060, - end: 8116, - }, }, ], span: Span { start: 653, end: 8116, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_parser.snap index ba5920b8a..1bfbb1dfd 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_nil_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,2196 +7,2544 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "result1", - span: Span { - start: 600, - end: 607, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result1", span: Span { - start: 611, - end: 614, + start: 600, + end: 607, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 611, + end: 614, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 611, + end: 620, + }, + }, span: Span { - start: 611, + start: 600, end: 620, }, }, - span: Span { - start: 600, - end: 620, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result2", - span: Span { - start: 638, - end: 645, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result2", span: Span { - start: 649, - end: 652, + start: 638, + end: 645, }, }, ), - selector: Unary( - "notNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 649, + end: 652, + }, + }, + ), + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 649, + end: 659, + }, + }, span: Span { - start: 649, + start: 638, end: 659, }, }, - span: Span { - start: 638, - end: 659, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result3", - span: Span { - start: 1172, - end: 1179, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result3", span: Span { - start: 1183, - end: 1186, + start: 1172, + end: 1179, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 1187, - end: 1193, + start: 1183, + end: 1186, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "default", - ), - Span { - start: 1195, - end: 1204, - }, - ), - ], - span: Span { - start: 1194, - end: 1205, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 1187, + end: 1193, + }, }, - }, + ], ), - ], - is_cast: false, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "default", + ), + Span { + start: 1195, + end: 1204, + }, + ), + }, + ], + span: Span { + start: 1194, + end: 1205, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1183, + end: 1205, + }, + }, span: Span { - start: 1183, + start: 1172, end: 1205, }, }, - span: Span { - start: 1172, - end: 1205, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result4", - span: Span { - start: 1259, - end: 1266, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result4", span: Span { - start: 1270, - end: 1273, + start: 1259, + end: 1266, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 1274, - end: 1283, + start: 1270, + end: 1273, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 1286, - end: 1289, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 1274, + end: 1283, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "val", - span: Span { - start: 1292, - end: 1295, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 1286, + end: 1289, }, - ), - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 1, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 1292, + end: 1295, + }, + }, ), - Span { - start: 1298, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 1, + ), + Span { + start: 1298, + end: 1299, + }, + ), + ], + is_cast: false, + span: Span { + start: 1292, end: 1299, }, - ), - ], - is_cast: false, - span: Span { - start: 1292, - end: 1299, + }, }, + ], + span: Span { + start: 1284, + end: 1300, }, - ], - span: Span { - start: 1284, - end: 1300, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1270, + end: 1300, + }, + }, span: Span { - start: 1270, + start: 1259, end: 1300, }, }, - span: Span { - start: 1259, - end: 1300, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result5", - span: Span { - start: 1345, - end: 1352, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result5", span: Span { - start: 1356, - end: 1359, + start: 1345, + end: 1352, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 1360, - end: 1366, + start: 1356, + end: 1359, }, }, - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 1379, - end: 1388, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 1360, + end: 1366, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "was nil", - ), - Span { - start: 1368, - end: 1377, - }, - ), - ], - span: Span { - start: 1367, - end: 1378, + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 1379, + end: 1388, + }, }, - }, + ], ), - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 1391, - end: 1394, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "was nil", + ), + Span { + start: 1368, + end: 1377, + }, + ), }, + ], + span: Span { + start: 1367, + end: 1378, }, - ], - body: [ - Literal( - String( - "was not nil", - ), - Span { - start: 1397, - end: 1410, + }, + ), + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 1391, + end: 1394, + }, }, - ), - ], - span: Span { - start: 1389, - end: 1411, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "was not nil", + ), + Span { + start: 1397, + end: 1410, + }, + ), + }, + ], + span: Span { + start: 1389, + end: 1411, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 1356, + end: 1411, + }, + }, span: Span { - start: 1356, + start: 1345, end: 1411, }, }, - span: Span { - start: 1345, - end: 1411, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result6", - span: Span { - start: 1473, - end: 1480, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result6", span: Span { - start: 1484, - end: 1487, + start: 1473, + end: 1480, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 1488, - end: 1497, + start: 1484, + end: 1487, }, }, - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 1521, - end: 1527, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 1488, + end: 1497, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 1500, - end: 1503, - }, + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 1521, + end: 1527, }, - ], - body: [ - Literal( - String( - "was not nil", - ), - Span { - start: 1506, - end: 1519, - }, - ), - ], - span: Span { - start: 1498, - end: 1520, }, - }, + ], ), - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "was nil", - ), - Span { - start: 1529, - end: 1538, + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 1500, + end: 1503, + }, }, - ), - ], - span: Span { - start: 1528, - end: 1539, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "was not nil", + ), + Span { + start: 1506, + end: 1519, + }, + ), + }, + ], + span: Span { + start: 1498, + end: 1520, + }, }, - }, - ), - ], - is_cast: false, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "was nil", + ), + Span { + start: 1529, + end: 1538, + }, + ), + }, + ], + span: Span { + start: 1528, + end: 1539, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 1484, + end: 1539, + }, + }, span: Span { - start: 1484, + start: 1473, end: 1539, }, }, - span: Span { - start: 1473, - end: 1539, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result7", - span: Span { - start: 2055, - end: 2062, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result7", span: Span { - start: 2066, - end: 2069, + start: 2055, + end: 2062, }, }, ), - selector: Unary( - "copy", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 2066, + end: 2069, + }, + }, + ), + selector: Unary( + "copy", + ), + arguments: [], + is_cast: false, + span: Span { + start: 2066, + end: 2074, + }, + }, span: Span { - start: 2066, + start: 2055, end: 2074, }, }, - span: Span { - start: 2055, - end: 2074, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result8", - span: Span { - start: 2075, - end: 2082, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result8", span: Span { - start: 2086, - end: 2089, + start: 2075, + end: 2082, }, }, ), - selector: Unary( - "deepCopy", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 2086, + end: 2089, + }, + }, + ), + selector: Unary( + "deepCopy", + ), + arguments: [], + is_cast: false, + span: Span { + start: 2086, + end: 2098, + }, + }, span: Span { - start: 2086, + start: 2075, end: 2098, }, }, - span: Span { - start: 2075, - end: 2098, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result9", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result9", + span: Span { + start: 2099, + end: 2106, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 2110, + end: 2113, + }, + }, + ), + selector: Unary( + "shallowCopy", + ), + arguments: [], + is_cast: false, span: Span { - start: 2099, - end: 2106, + start: 2110, + end: 2125, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 2110, - end: 2113, - }, - }, - ), - selector: Unary( - "shallowCopy", - ), - arguments: [], - is_cast: false, span: Span { - start: 2110, + start: 2099, end: 2125, }, }, - span: Span { - start: 2099, - end: 2125, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result10", - span: Span { - start: 2147, - end: 2155, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result10", span: Span { - start: 2159, - end: 2162, + start: 2147, + end: 2155, }, }, ), - selector: Unary( - "printString", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 2159, + end: 2162, + }, + }, + ), + selector: Unary( + "printString", + ), + arguments: [], + is_cast: false, + span: Span { + start: 2159, + end: 2174, + }, + }, span: Span { - start: 2159, + start: 2147, end: 2174, }, }, - span: Span { - start: 2147, - end: 2174, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result11", - span: Span { - start: 2719, - end: 2727, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result11", + span: Span { + start: 2719, + end: 2727, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 2732, - end: 2735, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 2736, - end: 2742, + start: 2732, + end: 2735, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 10, - ), - Span { - start: 2744, - end: 2746, - }, - ), - ], - span: Span { - start: 2743, - end: 2747, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 2736, + end: 2742, + }, }, - }, + ], ), - ], - is_cast: false, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 10, + ), + Span { + start: 2744, + end: 2746, + }, + ), + }, + ], + span: Span { + start: 2743, + end: 2747, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 2732, + end: 2747, + }, + }, span: Span { - start: 2732, - end: 2747, + start: 2731, + end: 2748, }, }, + selector: Binary( + "+", + ), + arguments: [ + Literal( + Integer( + 5, + ), + Span { + start: 2751, + end: 2752, + }, + ), + ], + is_cast: false, span: Span { start: 2731, - end: 2748, + end: 2752, }, }, - selector: Binary( - "+", - ), - arguments: [ - Literal( - Integer( - 5, - ), - Span { - start: 2751, - end: 2752, - }, - ), - ], - is_cast: false, span: Span { - start: 2731, + start: 2719, end: 2752, }, }, - span: Span { - start: 2719, - end: 2752, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result12", - span: Span { - start: 2812, - end: 2820, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result12", + span: Span { + start: 2812, + end: 2820, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 2825, - end: 2828, - }, - }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 2829, - end: 2835, + start: 2825, + end: 2828, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "hello", - ), - Span { - start: 2837, - end: 2844, - }, - ), - ], - span: Span { - start: 2836, - end: 2845, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 2829, + end: 2835, + }, }, - }, + ], ), - ], - is_cast: false, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "hello", + ), + Span { + start: 2837, + end: 2844, + }, + ), + }, + ], + span: Span { + start: 2836, + end: 2845, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 2825, + end: 2845, + }, + }, span: Span { - start: 2825, - end: 2845, + start: 2824, + end: 2846, }, }, + selector: Unary( + "uppercase", + ), + arguments: [], + is_cast: false, span: Span { start: 2824, - end: 2846, + end: 2856, }, }, - selector: Unary( - "uppercase", - ), - arguments: [], - is_cast: false, span: Span { - start: 2824, + start: 2812, end: 2856, }, }, - span: Span { - start: 2812, - end: 2856, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result13", - span: Span { - start: 2934, - end: 2942, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result13", span: Span { - start: 2946, - end: 2949, + start: 2934, + end: 2942, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 2950, - end: 2956, + start: 2946, + end: 2949, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 2958, - end: 2961, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 2950, + end: 2956, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 2962, - end: 2968, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 2958, + end: 2961, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "nested default", - ), - Span { - start: 2970, - end: 2986, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 2962, + end: 2968, }, - ), + }, ], - span: Span { - start: 2969, - end: 2987, - }, + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "nested default", + ), + Span { + start: 2970, + end: 2986, + }, + ), + }, + ], + span: Span { + start: 2969, + end: 2987, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 2958, + end: 2987, }, - ), - ], - is_cast: false, - span: Span { - start: 2958, - end: 2987, + }, }, + ], + span: Span { + start: 2957, + end: 2988, }, - ], - span: Span { - start: 2957, - end: 2988, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 2946, + end: 2988, + }, + }, span: Span { - start: 2946, + start: 2934, end: 2988, }, }, - span: Span { - start: 2934, - end: 2988, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result14", - span: Span { - start: 3047, - end: 3055, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result14", span: Span { - start: 3059, - end: 3062, + start: 3047, + end: 3055, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 3063, - end: 3069, + start: 3059, + end: 3062, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "nil", - span: Span { - start: 3071, - end: 3074, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 3063, + end: 3069, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, + expression: Identifier( + Identifier { + name: "nil", + span: Span { + start: 3071, + end: 3074, + }, + }, + ), }, - ), - ], - span: Span { - start: 3070, - end: 3075, + ], + span: Span { + start: 3070, + end: 3075, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 3059, + end: 3075, + }, + }, span: Span { - start: 3059, + start: 3047, end: 3075, }, }, - span: Span { - start: 3047, - end: 3075, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result15", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result15", + span: Span { + start: 3588, + end: 3596, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 3600, + end: 3603, + }, + }, + ), + selector: Binary( + "=:=", + ), + arguments: [ + Identifier( + Identifier { + name: "nil", + span: Span { + start: 3608, + end: 3611, + }, + }, + ), + ], + is_cast: false, span: Span { - start: 3588, - end: 3596, + start: 3600, + end: 3611, }, }, - ), - value: MessageSend { - receiver: Identifier( + span: Span { + start: 3588, + end: 3611, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result16", span: Span { - start: 3600, - end: 3603, + start: 3661, + end: 3669, }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Identifier( + value: MessageSend { + receiver: Identifier( Identifier { name: "nil", span: Span { - start: 3608, - end: 3611, + start: 3673, + end: 3676, }, }, ), - ], - is_cast: false, - span: Span { - start: 3600, - end: 3611, - }, - }, - span: Span { - start: 3588, - end: 3611, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "result16", + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + Integer( + 0, + ), + Span { + start: 3681, + end: 3682, + }, + ), + ], + is_cast: false, span: Span { - start: 3661, - end: 3669, + start: 3673, + end: 3682, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 3673, - end: 3676, - }, - }, - ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - Integer( - 0, - ), - Span { - start: 3681, - end: 3682, - }, - ), - ], - is_cast: false, span: Span { - start: 3673, + start: 3661, end: 3682, }, }, - span: Span { - start: 3661, - end: 3682, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result17", - span: Span { - start: 3698, - end: 3706, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result17", span: Span { - start: 3710, - end: 3713, + start: 3698, + end: 3706, }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( - String( - "", - ), - Span { - start: 3718, - end: 3720, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 3710, + end: 3713, + }, }, ), - ], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + String( + "", + ), + Span { + start: 3718, + end: 3720, + }, + ), + ], + is_cast: false, + span: Span { + start: 3710, + end: 3720, + }, + }, span: Span { - start: 3710, + start: 3698, end: 3720, }, }, - span: Span { - start: 3698, - end: 3720, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result18", - span: Span { - start: 3735, - end: 3743, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result18", span: Span { - start: 3747, - end: 3750, + start: 3735, + end: 3743, }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Identifier( + value: MessageSend { + receiver: Identifier( Identifier { - name: "false", + name: "nil", span: Span { - start: 3755, - end: 3760, + start: 3747, + end: 3750, }, }, ), - ], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Identifier( + Identifier { + name: "false", + span: Span { + start: 3755, + end: 3760, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 3747, + end: 3760, + }, + }, span: Span { - start: 3747, + start: 3735, end: 3760, }, }, - span: Span { - start: 3735, - end: 3760, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result19", - span: Span { - start: 4309, - end: 4317, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result19", + span: Span { + start: 4309, + end: 4317, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 4321, - end: 4324, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 4321, + end: 4324, + }, }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4321, + end: 4330, }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 4331, + end: 4335, + }, + }, + ], ), - selector: Unary( - "isNil", - ), - arguments: [], + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 4337, + end: 4341, + }, + }, + ), + }, + ], + span: Span { + start: 4336, + end: 4342, + }, + }, + ), + ], is_cast: false, span: Span { start: 4321, - end: 4330, + end: 4342, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "and:", - span: Span { - start: 4331, - end: 4335, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 4337, - end: 4341, - }, - }, - ), - ], - span: Span { - start: 4336, - end: 4342, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 4321, + start: 4309, end: 4342, }, }, - span: Span { - start: 4309, - end: 4342, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result20", - span: Span { - start: 4356, - end: 4364, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result20", + span: Span { + start: 4356, + end: 4364, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 4368, - end: 4371, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 4368, + end: 4371, + }, }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4368, + end: 4377, }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 4378, + end: 4381, + }, + }, + ], ), - selector: Unary( - "isNil", - ), - arguments: [], + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "false", + span: Span { + start: 4383, + end: 4388, + }, + }, + ), + }, + ], + span: Span { + start: 4382, + end: 4389, + }, + }, + ), + ], is_cast: false, span: Span { start: 4368, - end: 4377, + end: 4389, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "or:", - span: Span { - start: 4378, - end: 4381, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "false", - span: Span { - start: 4383, - end: 4388, - }, - }, - ), - ], - span: Span { - start: 4382, - end: 4389, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 4368, + start: 4356, end: 4389, }, }, - span: Span { - start: 4356, - end: 4389, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result21", - span: Span { - start: 4420, - end: 4428, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result21", + span: Span { + start: 4420, + end: 4428, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 4432, - end: 4435, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 4432, + end: 4435, + }, }, + ), + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4432, + end: 4442, }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 4443, + end: 4447, + }, + }, + ], ), - selector: Unary( - "notNil", - ), - arguments: [], + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 4449, + end: 4453, + }, + }, + ), + }, + ], + span: Span { + start: 4448, + end: 4454, + }, + }, + ), + ], is_cast: false, span: Span { start: 4432, - end: 4442, + end: 4454, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "and:", - span: Span { - start: 4443, - end: 4447, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 4449, - end: 4453, - }, - }, - ), - ], - span: Span { - start: 4448, - end: 4454, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 4432, + start: 4420, end: 4454, }, }, - span: Span { - start: 4420, - end: 4454, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result22", - span: Span { - start: 4485, - end: 4493, - }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 4497, - end: 4500, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result22", + span: Span { + start: 4485, + end: 4493, + }, + }, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 4497, + end: 4500, + }, }, + ), + selector: Unary( + "notNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4497, + end: 4507, }, + }, + selector: Keyword( + [ + KeywordPart { + keyword: "or:", + span: Span { + start: 4508, + end: 4511, + }, + }, + ], ), - selector: Unary( - "notNil", - ), - arguments: [], + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "true", + span: Span { + start: 4513, + end: 4517, + }, + }, + ), + }, + ], + span: Span { + start: 4512, + end: 4518, + }, + }, + ), + ], is_cast: false, span: Span { start: 4497, - end: 4507, + end: 4518, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "or:", - span: Span { - start: 4508, - end: 4511, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "true", - span: Span { - start: 4513, - end: 4517, - }, - }, - ), - ], - span: Span { - start: 4512, - end: 4518, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 4497, + start: 4485, end: 4518, }, }, - span: Span { - start: 4485, - end: 4518, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result23", - span: Span { - start: 4574, - end: 4582, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result23", + span: Span { + start: 4574, + end: 4582, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 4586, - end: 4589, + ), + value: MessageSend { + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 4586, + end: 4589, + }, }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 4586, + end: 4595, }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, - span: Span { - start: 4586, - end: 4595, }, - }, - selector: Keyword( - [ - KeywordPart { - keyword: "ifTrue:", - span: Span { - start: 4596, - end: 4603, + selector: Keyword( + [ + KeywordPart { + keyword: "ifTrue:", + span: Span { + start: 4596, + end: 4603, + }, }, - }, - KeywordPart { - keyword: "ifFalse:", - span: Span { - start: 4615, - end: 4623, + KeywordPart { + keyword: "ifFalse:", + span: Span { + start: 4615, + end: 4623, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "is nil", - ), - Span { - start: 4605, - end: 4613, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "is nil", + ), + Span { + start: 4605, + end: 4613, + }, + ), }, - ), - ], - span: Span { - start: 4604, - end: 4614, + ], + span: Span { + start: 4604, + end: 4614, + }, }, - }, - ), - Block( - Block { - parameters: [], - body: [ - Literal( - String( - "not nil", - ), - Span { - start: 4625, - end: 4634, + ), + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + String( + "not nil", + ), + Span { + start: 4625, + end: 4634, + }, + ), }, - ), - ], - span: Span { - start: 4624, - end: 4635, + ], + span: Span { + start: 4624, + end: 4635, + }, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 4586, + end: 4635, + }, + }, span: Span { - start: 4586, + start: 4574, end: 4635, }, }, - span: Span { - start: 4574, - end: 4635, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result24", - span: Span { - start: 5156, - end: 5164, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result24", span: Span { - start: 5168, - end: 5171, + start: 5156, + end: 5164, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 5172, - end: 5178, + start: 5168, + end: 5171, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Literal( - Integer( - 1, - ), - Span { - start: 5180, - end: 5181, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 5172, + end: 5178, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { + expression: MessageSend { receiver: Literal( Integer( - 2, + 1, ), Span { - start: 5184, - end: 5185, + start: 5180, + end: 5181, }, ), selector: Binary( - "*", + "+", ), arguments: [ - Literal( - Integer( - 3, + MessageSend { + receiver: Literal( + Integer( + 2, + ), + Span { + start: 5184, + end: 5185, + }, ), - Span { - start: 5188, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 3, + ), + Span { + start: 5188, + end: 5189, + }, + ), + ], + is_cast: false, + span: Span { + start: 5184, end: 5189, }, - ), + }, ], is_cast: false, span: Span { - start: 5184, + start: 5180, end: 5189, }, }, - ], - is_cast: false, - span: Span { - start: 5180, - end: 5189, }, + ], + span: Span { + start: 5179, + end: 5190, }, - ], - span: Span { - start: 5179, - end: 5190, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 5168, + end: 5190, + }, + }, span: Span { - start: 5168, + start: 5156, end: 5190, }, }, - span: Span { - start: 5156, - end: 5190, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result25", - span: Span { - start: 5244, - end: 5252, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result25", span: Span { - start: 5256, - end: 5259, + start: 5244, + end: 5252, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 5260, - end: 5269, + start: 5256, + end: 5259, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [ - BlockParameter { - name: "val", - span: Span { - start: 5272, - end: 5275, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 5260, + end: 5269, }, - ], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "val", - span: Span { - start: 5278, - end: 5281, - }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [ + BlockParameter { + name: "val", + span: Span { + start: 5272, + end: 5275, }, - ), - selector: Binary( - "+", - ), - arguments: [ - MessageSend { - receiver: Literal( - Integer( - 100, - ), - Span { - start: 5284, - end: 5287, + }, + ], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "val", + span: Span { + start: 5278, + end: 5281, + }, }, ), selector: Binary( - "*", + "+", ), arguments: [ - Literal( - Integer( - 2, + MessageSend { + receiver: Literal( + Integer( + 100, + ), + Span { + start: 5284, + end: 5287, + }, ), - Span { - start: 5290, + selector: Binary( + "*", + ), + arguments: [ + Literal( + Integer( + 2, + ), + Span { + start: 5290, + end: 5291, + }, + ), + ], + is_cast: false, + span: Span { + start: 5284, end: 5291, }, - ), + }, ], is_cast: false, span: Span { - start: 5284, + start: 5278, end: 5291, }, }, - ], - is_cast: false, - span: Span { - start: 5278, - end: 5291, }, + ], + span: Span { + start: 5270, + end: 5292, }, - ], - span: Span { - start: 5270, - end: 5292, }, - }, - ), - ], - is_cast: false, + ), + ], + is_cast: false, + span: Span { + start: 5256, + end: 5292, + }, + }, span: Span { - start: 5256, + start: 5244, end: 5292, }, }, - span: Span { - start: 5244, - end: 5292, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "check1", - span: Span { - start: 5871, - end: 5877, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "check1", span: Span { - start: 5881, - end: 5884, + start: 5871, + end: 5877, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 5881, + end: 5884, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 5881, + end: 5890, + }, + }, span: Span { - start: 5881, + start: 5871, end: 5890, }, }, - span: Span { - start: 5871, - end: 5890, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "check2", + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "check2", + span: Span { + start: 5891, + end: 5897, + }, + }, + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 5901, + end: 5904, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, span: Span { - start: 5891, - end: 5897, + start: 5901, + end: 5910, }, }, - ), - value: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", - span: Span { - start: 5901, - end: 5904, - }, - }, - ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, span: Span { - start: 5901, + start: 5891, end: 5910, }, }, - span: Span { - start: 5891, - end: 5910, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "check3", - span: Span { - start: 5913, - end: 5919, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "check3", span: Span { - start: 5923, - end: 5926, + start: 5913, + end: 5919, }, }, ), - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 5923, + end: 5926, + }, + }, + ), + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 5923, + end: 5932, + }, + }, span: Span { - start: 5923, + start: 5913, end: 5932, }, }, - span: Span { - start: 5913, - end: 5932, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result26", - span: Span { - start: 5933, - end: 5941, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "check1", + name: "result26", span: Span { - start: 5945, - end: 5951, + start: 5933, + end: 5941, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "and:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "check1", span: Span { - start: 5952, - end: 5956, + start: 5945, + end: 5951, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - MessageSend { - receiver: Identifier( - Identifier { - name: "check2", - span: Span { - start: 5958, - end: 5964, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 5952, + end: 5956, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "and:", - span: Span { - start: 5965, - end: 5969, + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "check2", + span: Span { + start: 5958, + end: 5964, + }, }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Identifier( - Identifier { - name: "check3", - span: Span { - start: 5971, - end: 5977, - }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "and:", + span: Span { + start: 5965, + end: 5969, }, - ), + }, ], - span: Span { - start: 5970, - end: 5978, - }, + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Identifier( + Identifier { + name: "check3", + span: Span { + start: 5971, + end: 5977, + }, + }, + ), + }, + ], + span: Span { + start: 5970, + end: 5978, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 5958, + end: 5978, }, - ), - ], - is_cast: false, - span: Span { - start: 5958, - end: 5978, + }, }, + ], + span: Span { + start: 5957, + end: 5979, }, - ], - span: Span { - start: 5957, - end: 5979, }, - }, - ), - ], - is_cast: false, - span: Span { - start: 5945, - end: 5979, - }, - }, - span: Span { - start: 5933, - end: 5979, - }, - }, - Assignment { - target: Identifier( - Identifier { - name: "maybeValue", + ), + ], + is_cast: false, span: Span { - start: 6028, - end: 6038, + start: 5945, + end: 5979, }, }, - ), - value: Identifier( - Identifier { - name: "nil", - span: Span { - start: 6042, - end: 6045, - }, + span: Span { + start: 5933, + end: 5979, }, - ), - span: Span { - start: 6028, - end: 6045, }, }, - Assignment { - target: Identifier( - Identifier { - name: "result27", - span: Span { - start: 6046, - end: 6054, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { name: "maybeValue", span: Span { - start: 6058, - end: 6068, + start: 6028, + end: 6038, }, }, ), - selector: Unary( - "isNil", + value: Identifier( + Identifier { + name: "nil", + span: Span { + start: 6042, + end: 6045, + }, + }, ), - arguments: [], - is_cast: false, span: Span { - start: 6058, - end: 6074, + start: 6028, + end: 6045, }, }, - span: Span { - start: 6046, - end: 6074, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result28", - span: Span { - start: 6612, - end: 6620, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result27", span: Span { - start: 6624, - end: 6627, + start: 6046, + end: 6054, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNil:", - span: Span { - start: 6628, - end: 6634, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 6636, - end: 6638, - }, - ), - ], + value: MessageSend { + receiver: Identifier( + Identifier { + name: "maybeValue", span: Span { - start: 6635, - end: 6639, + start: 6058, + end: 6068, }, }, ), - ], - is_cast: false, + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, + span: Span { + start: 6058, + end: 6074, + }, + }, span: Span { - start: 6624, - end: 6639, + start: 6046, + end: 6074, }, }, - span: Span { - start: 6612, - end: 6639, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result29", - span: Span { - start: 6700, - end: 6708, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "nil", + name: "result28", span: Span { - start: 6712, - end: 6715, + start: 6612, + end: 6620, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 6716, - end: 6725, + start: 6624, + end: 6627, }, }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Integer( - 42, - ), - Span { - start: 6727, - end: 6729, - }, - ), - ], - span: Span { - start: 6726, - end: 6730, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNil:", + span: Span { + start: 6628, + end: 6634, + }, }, - }, + ], ), - ], - is_cast: false, + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 42, + ), + Span { + start: 6636, + end: 6638, + }, + ), + }, + ], + span: Span { + start: 6635, + end: 6639, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 6624, + end: 6639, + }, + }, span: Span { - start: 6712, - end: 6730, + start: 6612, + end: 6639, }, }, - span: Span { - start: 6700, - end: 6730, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "result30", - span: Span { - start: 6834, - end: 6842, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result29", + span: Span { + start: 6700, + end: 6708, + }, }, - }, - ), - value: MessageSend { - receiver: Parenthesized { - expression: MessageSend { - receiver: Identifier( - Identifier { - name: "nil", + ), + value: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", + span: Span { + start: 6712, + end: 6715, + }, + }, + ), + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", span: Span { - start: 6847, - end: 6850, + start: 6716, + end: 6725, }, }, - ), - selector: Keyword( - [ - KeywordPart { - keyword: "ifNotNil:", - span: Span { - start: 6851, - end: 6860, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( Integer( - 9999, + 42, ), Span { - start: 6862, - end: 6866, + start: 6727, + end: 6729, }, ), - ], + }, + ], + span: Span { + start: 6726, + end: 6730, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 6712, + end: 6730, + }, + }, + span: Span { + start: 6700, + end: 6730, + }, + }, + }, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "result30", + span: Span { + start: 6834, + end: 6842, + }, + }, + ), + value: MessageSend { + receiver: Parenthesized { + expression: MessageSend { + receiver: Identifier( + Identifier { + name: "nil", span: Span { - start: 6861, - end: 6867, + start: 6847, + end: 6850, }, }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "ifNotNil:", + span: Span { + start: 6851, + end: 6860, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Integer( + 9999, + ), + Span { + start: 6862, + end: 6866, + }, + ), + }, + ], + span: Span { + start: 6861, + end: 6867, + }, + }, + ), + ], + is_cast: false, + span: Span { + start: 6847, + end: 6867, + }, + }, span: Span { - start: 6847, - end: 6867, + start: 6846, + end: 6868, }, }, + selector: Unary( + "isNil", + ), + arguments: [], + is_cast: false, span: Span { start: 6846, - end: 6868, + end: 6874, }, }, - selector: Unary( - "isNil", - ), - arguments: [], - is_cast: false, span: Span { - start: 6846, + start: 6834, end: 6874, }, }, - span: Span { - start: 6834, - end: 6874, - }, }, ], span: Span { start: 600, end: 6874, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_set_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_set_parser.snap index 79db8f44f..97033f05b 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_set_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_set_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,114 +7,162 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "colors", - span: Span { - start: 138, - end: 144, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "colors", + span: Span { + start: 138, + end: 144, + }, }, - }, - ), - value: MessageSend { - receiver: ClassReference { - name: Identifier { - name: "Set", + ), + value: MessageSend { + receiver: ClassReference { + name: Identifier { + name: "Set", + span: Span { + start: 148, + end: 151, + }, + }, span: Span { start: 148, end: 151, }, }, + selector: Keyword( + [ + KeywordPart { + keyword: "fromList:", + span: Span { + start: 152, + end: 161, + }, + }, + ], + ), + arguments: [ + Block( + Block { + parameters: [], + body: [ + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Literal( + Symbol( + "red", + ), + Span { + start: 163, + end: 167, + }, + ), + }, + ], + span: Span { + start: 162, + end: 163, + }, + }, + ), + ], + is_cast: false, span: Span { start: 148, - end: 151, + end: 163, }, }, - selector: Keyword( - [ - KeywordPart { - keyword: "fromList:", - span: Span { - start: 152, - end: 161, - }, - }, - ], - ), - arguments: [ - Block( - Block { - parameters: [], - body: [ - Literal( - Symbol( - "red", - ), - Span { - start: 163, - end: 167, - }, - ), - ], - span: Span { - start: 162, - end: 163, - }, - }, - ), - ], - is_cast: false, span: Span { - start: 148, + start: 138, end: 163, }, }, - span: Span { - start: 138, - end: 163, - }, }, - Error { - message: "Unexpected token: expected expression, found ,", - span: Span { - start: 167, - end: 168, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ,", + span: Span { + start: 167, + end: 168, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 182, - end: 183, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 182, + end: 183, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 229, - end: 230, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 229, + end: 230, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 649, - end: 650, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 649, + end: 650, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 708, - end: 709, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 708, + end: 709, + }, }, }, - Error { - message: "Unexpected token: expected expression, found ]", - span: Span { - start: 765, - end: 766, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Error { + message: "Unexpected token: expected expression, found ]", + span: Span { + start: 765, + end: 766, + }, }, }, ], @@ -123,7 +170,7 @@ Module { start: 138, end: 918, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span { diff --git a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_string_parser.snap b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_string_parser.snap index 4a73ccfb6..0bc560b2e 100644 --- a/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_string_parser.snap +++ b/test-package-compiler/tests/snapshots/compiler_tests__ws_stdlib_string_parser.snap @@ -1,6 +1,5 @@ --- source: test-package-compiler/tests/compiler_tests.rs -assertion_line: 70 expression: output --- AST: @@ -8,518 +7,590 @@ Module { classes: [], method_definitions: [], expressions: [ - Assignment { - target: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 116, - end: 124, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 116, + end: 124, + }, + }, + ), + value: Literal( + String( + "Hello", + ), + Span { + start: 128, + end: 135, }, - }, - ), - value: Literal( - String( - "Hello", ), - Span { - start: 128, + span: Span { + start: 116, end: 135, }, - ), - span: Span { - start: 116, - end: 135, }, }, - Assignment { - target: Identifier( - Identifier { - name: "name", - span: Span { - start: 136, - end: 140, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "name", + span: Span { + start: 136, + end: 140, + }, + }, + ), + value: Literal( + String( + "World", + ), + Span { + start: 144, + end: 151, }, - }, - ), - value: Literal( - String( - "World", ), - Span { - start: 144, + span: Span { + start: 136, end: 151, }, - ), - span: Span { - start: 136, - end: 151, }, }, - Assignment { - target: Identifier( - Identifier { - name: "message", - span: Span { - start: 170, - end: 177, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "message", + span: Span { + start: 170, + end: 177, + }, }, - }, - ), - value: MessageSend { - receiver: MessageSend { + ), + value: MessageSend { receiver: MessageSend { - receiver: Identifier( - Identifier { - name: "greeting", - span: Span { - start: 181, - end: 189, + receiver: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 181, + end: 189, + }, }, + ), + selector: Binary( + "++", + ), + arguments: [ + Literal( + String( + ", ", + ), + Span { + start: 193, + end: 197, + }, + ), + ], + is_cast: false, + span: Span { + start: 181, + end: 197, }, - ), + }, selector: Binary( "++", ), arguments: [ - Literal( - String( - ", ", - ), - Span { - start: 193, - end: 197, + Identifier( + Identifier { + name: "name", + span: Span { + start: 201, + end: 205, + }, }, ), ], is_cast: false, span: Span { start: 181, - end: 197, + end: 205, }, }, selector: Binary( "++", ), arguments: [ - Identifier( - Identifier { - name: "name", - span: Span { - start: 201, - end: 205, - }, + Literal( + String( + "!", + ), + Span { + start: 209, + end: 212, }, ), ], is_cast: false, span: Span { start: 181, - end: 205, + end: 212, }, }, - selector: Binary( - "++", - ), - arguments: [ - Literal( - String( - "!", - ), - Span { - start: 209, - end: 212, - }, - ), - ], - is_cast: false, span: Span { - start: 181, + start: 170, end: 212, }, }, - span: Span { - start: 170, - end: 212, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "len", - span: Span { - start: 231, - end: 234, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "greeting", + name: "len", span: Span { - start: 238, - end: 246, + start: 231, + end: 234, }, }, ), - selector: Unary( - "length", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 238, + end: 246, + }, + }, + ), + selector: Unary( + "length", + ), + arguments: [], + is_cast: false, + span: Span { + start: 238, + end: 253, + }, + }, span: Span { - start: 238, + start: 231, end: 253, }, }, - span: Span { - start: 231, - end: 253, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEqual", - span: Span { - start: 276, - end: 283, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "hello", - ), - Span { - start: 287, - end: 294, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEqual", + span: Span { + start: 276, + end: 283, + }, }, ), - selector: Binary( - "=:=", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( "hello", ), Span { - start: 299, - end: 306, + start: 287, + end: 294, }, ), - ], - is_cast: false, + selector: Binary( + "=:=", + ), + arguments: [ + Literal( + String( + "hello", + ), + Span { + start: 299, + end: 306, + }, + ), + ], + is_cast: false, + span: Span { + start: 287, + end: 306, + }, + }, span: Span { - start: 287, + start: 276, end: 306, }, }, - span: Span { - start: 276, - end: 306, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isLess", - span: Span { - start: 307, - end: 313, - }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "apple", - ), - Span { - start: 317, - end: 324, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isLess", + span: Span { + start: 307, + end: 313, + }, }, ), - selector: Binary( - "<", - ), - arguments: [ - Literal( + value: MessageSend { + receiver: Literal( String( - "banana", + "apple", ), Span { - start: 327, - end: 335, + start: 317, + end: 324, }, ), - ], - is_cast: false, + selector: Binary( + "<", + ), + arguments: [ + Literal( + String( + "banana", + ), + Span { + start: 327, + end: 335, + }, + ), + ], + is_cast: false, + span: Span { + start: 317, + end: 335, + }, + }, span: Span { - start: 317, + start: 307, end: 335, }, }, - span: Span { - start: 307, - end: 335, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "upper", - span: Span { - start: 362, - end: 367, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "greeting", + name: "upper", span: Span { - start: 371, - end: 379, + start: 362, + end: 367, }, }, ), - selector: Unary( - "uppercase", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "greeting", + span: Span { + start: 371, + end: 379, + }, + }, + ), + selector: Unary( + "uppercase", + ), + arguments: [], + is_cast: false, + span: Span { + start: 371, + end: 389, + }, + }, span: Span { - start: 371, + start: 362, end: 389, }, }, - span: Span { - start: 362, - end: 389, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "lower", - span: Span { - start: 390, - end: 395, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "upper", + name: "lower", span: Span { - start: 399, - end: 404, + start: 390, + end: 395, }, }, ), - selector: Unary( - "lowercase", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "upper", + span: Span { + start: 399, + end: 404, + }, + }, + ), + selector: Unary( + "lowercase", + ), + arguments: [], + is_cast: false, + span: Span { + start: 399, + end: 414, + }, + }, span: Span { - start: 399, + start: 390, end: 414, }, }, - span: Span { - start: 390, - end: 414, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "isEmpty", - span: Span { - start: 434, - end: 441, + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( + Identifier { + name: "isEmpty", + span: Span { + start: 434, + end: 441, + }, }, - }, - ), - value: MessageSend { - receiver: Literal( - String( - "", + ), + value: MessageSend { + receiver: Literal( + String( + "", + ), + Span { + start: 445, + end: 447, + }, ), - Span { + selector: Unary( + "isEmpty", + ), + arguments: [], + is_cast: false, + span: Span { start: 445, - end: 447, + end: 455, }, - ), - selector: Unary( - "isEmpty", - ), - arguments: [], - is_cast: false, + }, span: Span { - start: 445, + start: 434, end: 455, }, }, - span: Span { - start: 434, - end: 455, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "hasContent", - span: Span { - start: 456, - end: 466, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "hasContent", span: Span { - start: 470, - end: 477, + start: 456, + end: 466, }, }, ), - selector: Unary( - "isNotEmpty", - ), - arguments: [], - is_cast: false, + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", + span: Span { + start: 470, + end: 477, + }, + }, + ), + selector: Unary( + "isNotEmpty", + ), + arguments: [], + is_cast: false, + span: Span { + start: 470, + end: 488, + }, + }, span: Span { - start: 470, + start: 456, end: 488, }, }, - span: Span { - start: 456, - end: 488, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "found", - span: Span { - start: 510, - end: 515, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "found", span: Span { - start: 519, - end: 526, + start: 510, + end: 515, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "includesSubstring:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 527, - end: 545, + start: 519, + end: 526, }, }, - ], - ), - arguments: [ - Literal( - String( - "World", - ), - Span { - start: 546, - end: 553, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "includesSubstring:", + span: Span { + start: 527, + end: 545, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "World", + ), + Span { + start: 546, + end: 553, + }, + ), + ], + is_cast: false, + span: Span { + start: 519, + end: 553, + }, + }, span: Span { - start: 519, + start: 510, end: 553, }, }, - span: Span { - start: 510, - end: 553, - }, }, - Assignment { - target: Identifier( - Identifier { - name: "starts", - span: Span { - start: 554, - end: 560, - }, - }, - ), - value: MessageSend { - receiver: Identifier( + ExpressionStatement { + comments: CommentAttachment { + leading: [], + trailing: None, + }, + expression: Assignment { + target: Identifier( Identifier { - name: "message", + name: "starts", span: Span { - start: 564, - end: 571, + start: 554, + end: 560, }, }, ), - selector: Keyword( - [ - KeywordPart { - keyword: "startsWith:", + value: MessageSend { + receiver: Identifier( + Identifier { + name: "message", span: Span { - start: 572, - end: 583, + start: 564, + end: 571, }, }, - ], - ), - arguments: [ - Literal( - String( - "Hello", - ), - Span { - start: 584, - end: 591, - }, ), - ], - is_cast: false, + selector: Keyword( + [ + KeywordPart { + keyword: "startsWith:", + span: Span { + start: 572, + end: 583, + }, + }, + ], + ), + arguments: [ + Literal( + String( + "Hello", + ), + Span { + start: 584, + end: 591, + }, + ), + ], + is_cast: false, + span: Span { + start: 564, + end: 591, + }, + }, span: Span { - start: 564, + start: 554, end: 591, }, }, - span: Span { - start: 554, - end: 591, - }, }, ], span: Span { start: 116, end: 591, }, - leading_comments: [ + file_leading_comments: [ Comment { content: "// Copyright 2026 James Casey", span: Span {