From d3253ba66b2fc80f2b4ce42e1b3f336157aa2986 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Fri, 27 Feb 2026 16:28:34 +0100 Subject: [PATCH] Parser: Fix lambda block detection --- src/analyze.c | 15 ++++ src/analyze_helpers.c | 20 +++++ test/analyze/block_test.rb | 88 +++++++++++++++++++ ...block_f5e4979fcc19c687666302801b177207.txt | 26 ++++++ ...arams_b65c3166e979a0611147e115ca0f38d9.txt | 26 ++++++ ...block_ea5c1b1e28ffb0998e6a1e21bed2b8c4.txt | 26 ++++++ ...arams_fe9cd507d138aa98d210641671de0b17.txt | 26 ++++++ ...e_tag_d6ae6032fea680b0f28282eb89556a84.txt | 16 ++++ ...e_tag_54c06beb62800538f64bb1d77354f106.txt | 16 ++++ ...block_1946126146ae485822c40d7b0e816743.txt | 26 ++++++ ...block_7ab1eeb026e4a5427166556a3e7a49c2.txt | 26 ++++++ ...block_7d6f7e59ef4d8235f30fd5db189432ee.txt | 35 ++++++++ ...block_b43d364322f8991b6b31038fb151087c.txt | 35 ++++++++ ...block_0f1b91582217c885699c38df65576d83.txt | 35 ++++++++ ...block_64d15f18add0fc26b768522cd37c8e25.txt | 35 ++++++++ 15 files changed, 451 insertions(+) create mode 100644 test/snapshots/analyze/block_test/test_0025_stabby_lambda_with_do_block_f5e4979fcc19c687666302801b177207.txt create mode 100644 test/snapshots/analyze/block_test/test_0026_stabby_lambda_with_do_block_and_params_b65c3166e979a0611147e115ca0f38d9.txt create mode 100644 test/snapshots/analyze/block_test/test_0027_lambda_keyword_with_do_block_ea5c1b1e28ffb0998e6a1e21bed2b8c4.txt create mode 100644 test/snapshots/analyze/block_test/test_0028_lambda_keyword_with_do_block_and_params_fe9cd507d138aa98d210641671de0b17.txt create mode 100644 test/snapshots/analyze/block_test/test_0029_inline_stabby_lambda_with_do_end_in_single_tag_d6ae6032fea680b0f28282eb89556a84.txt create mode 100644 test/snapshots/analyze/block_test/test_0030_inline_lambda_keyword_with_do_end_in_single_tag_54c06beb62800538f64bb1d77354f106.txt create mode 100644 test/snapshots/analyze/block_test/test_0031_stabby_lambda_with_brace_block_1946126146ae485822c40d7b0e816743.txt create mode 100644 test/snapshots/analyze/block_test/test_0032_lambda_keyword_with_brace_block_7ab1eeb026e4a5427166556a3e7a49c2.txt create mode 100644 test/snapshots/analyze/block_test/test_0033_unclosed_stabby_lambda_with_do_block_7d6f7e59ef4d8235f30fd5db189432ee.txt create mode 100644 test/snapshots/analyze/block_test/test_0034_unclosed_stabby_lambda_with_brace_block_b43d364322f8991b6b31038fb151087c.txt create mode 100644 test/snapshots/analyze/block_test/test_0035_unclosed_lambda_keyword_with_do_block_0f1b91582217c885699c38df65576d83.txt create mode 100644 test/snapshots/analyze/block_test/test_0036_unclosed_lambda_keyword_with_brace_block_64d15f18add0fc26b768522cd37c8e25.txt diff --git a/src/analyze.c b/src/analyze.c index 9f84dd830..45e523208 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -240,6 +240,21 @@ static bool find_earliest_control_keyword_walker(const pm_node_t* node, void* da break; } + case PM_LAMBDA_NODE: { + pm_lambda_node_t* lambda = (pm_lambda_node_t*) node; + + bool has_do_opening = is_do_block(lambda->opening_loc); + bool has_brace_opening = is_brace_block(lambda->opening_loc); + bool has_valid_brace_closing = is_closing_brace(lambda->closing_loc); + + if (has_do_opening || (has_brace_opening && !has_valid_brace_closing)) { + current_type = CONTROL_TYPE_BLOCK; + keyword_offset = (uint32_t) (node->location.start - context->source_start); + } + + break; + } + case PM_NEXT_NODE: case PM_BREAK_NODE: case PM_RETURN_NODE: { diff --git a/src/analyze_helpers.c b/src/analyze_helpers.c index c7f37a3ff..b21af7c71 100644 --- a/src/analyze_helpers.c +++ b/src/analyze_helpers.c @@ -161,6 +161,15 @@ bool search_block_nodes(const pm_node_t* node, void* data) { if (has_opening && is_unclosed) { analyzed->block_node_count++; } } + if (node->type == PM_LAMBDA_NODE) { + pm_lambda_node_t* lambda_node = (pm_lambda_node_t*) node; + + bool has_opening = is_do_block(lambda_node->opening_loc) || is_brace_block(lambda_node->opening_loc); + bool is_unclosed = !has_valid_block_closing(lambda_node->opening_loc, lambda_node->closing_loc); + + if (has_opening && is_unclosed) { analyzed->block_node_count++; } + } + pm_visit_child_nodes(node, search_block_nodes, analyzed); return false; @@ -494,6 +503,17 @@ bool search_unclosed_control_flows(const pm_node_t* node, void* data) { break; } + case PM_LAMBDA_NODE: { + const pm_lambda_node_t* lambda_node = (const pm_lambda_node_t*) node; + bool has_opening = is_do_block(lambda_node->opening_loc) || is_brace_block(lambda_node->opening_loc); + + if (has_opening && !has_valid_block_closing(lambda_node->opening_loc, lambda_node->closing_loc)) { + analyzed->unclosed_control_flow_count++; + } + + break; + } + default: break; } diff --git a/test/analyze/block_test.rb b/test/analyze/block_test.rb index 49aaa79de..4d47f7f0c 100644 --- a/test/analyze/block_test.rb +++ b/test/analyze/block_test.rb @@ -209,5 +209,93 @@ class BlockTest < Minitest::Spec <% end %> HTML end + + test "stabby lambda with do block" do + assert_parsed_snapshot(<<~HTML) + <% content = -> do %> + Content + <% end %> + HTML + end + + test "stabby lambda with do block and params" do + assert_parsed_snapshot(<<~HTML) + <% content = ->(x) do %> + Content + <% end %> + HTML + end + + test "lambda keyword with do block" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda do %> + Content + <% end %> + HTML + end + + test "lambda keyword with do block and params" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda do |x| %> + Content + <% end %> + HTML + end + + test "inline stabby lambda with do/end in single tag" do + assert_parsed_snapshot(<<~HTML) + <% content = -> do; end %> + HTML + end + + test "inline lambda keyword with do/end in single tag" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda do; end %> + HTML + end + + test "stabby lambda with brace block" do + assert_parsed_snapshot(<<~HTML) + <% content = -> { %> + Content + <% } %> + HTML + end + + test "lambda keyword with brace block" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda { %> + Content + <% } %> + HTML + end + + test "unclosed stabby lambda with do block" do + assert_parsed_snapshot(<<~HTML) + <% content = -> do %> + Content + HTML + end + + test "unclosed stabby lambda with brace block" do + assert_parsed_snapshot(<<~HTML) + <% content = -> { %> + Content + HTML + end + + test "unclosed lambda keyword with do block" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda do %> + Content + HTML + end + + test "unclosed lambda keyword with brace block" do + assert_parsed_snapshot(<<~HTML) + <% content = lambda { %> + Content + HTML + end end end diff --git a/test/snapshots/analyze/block_test/test_0025_stabby_lambda_with_do_block_f5e4979fcc19c687666302801b177207.txt b/test/snapshots/analyze/block_test/test_0025_stabby_lambda_with_do_block_f5e4979fcc19c687666302801b177207.txt new file mode 100644 index 000000000..2f2f50af4 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0025_stabby_lambda_with_do_block_f5e4979fcc19c687666302801b177207.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0025_stabby lambda with do block" +input: |2- +<% content = -> do %> + Content +<% end %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = -> do " (location: (1:2)-(1:19)) + │ ├── tag_closing: "%>" (location: (1:19)-(1:21)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:21)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " end " (location: (3:2)-(3:7)) + │ └── tag_closing: "%>" (location: (3:7)-(3:9)) + │ + │ + └── @ HTMLTextNode (location: (3:9)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0026_stabby_lambda_with_do_block_and_params_b65c3166e979a0611147e115ca0f38d9.txt b/test/snapshots/analyze/block_test/test_0026_stabby_lambda_with_do_block_and_params_b65c3166e979a0611147e115ca0f38d9.txt new file mode 100644 index 000000000..ffeff34f4 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0026_stabby_lambda_with_do_block_and_params_b65c3166e979a0611147e115ca0f38d9.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0026_stabby lambda with do block and params" +input: |2- +<% content = ->(x) do %> + Content +<% end %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = ->(x) do " (location: (1:2)-(1:22)) + │ ├── tag_closing: "%>" (location: (1:22)-(1:24)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:24)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " end " (location: (3:2)-(3:7)) + │ └── tag_closing: "%>" (location: (3:7)-(3:9)) + │ + │ + └── @ HTMLTextNode (location: (3:9)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0027_lambda_keyword_with_do_block_ea5c1b1e28ffb0998e6a1e21bed2b8c4.txt b/test/snapshots/analyze/block_test/test_0027_lambda_keyword_with_do_block_ea5c1b1e28ffb0998e6a1e21bed2b8c4.txt new file mode 100644 index 000000000..57edeca30 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0027_lambda_keyword_with_do_block_ea5c1b1e28ffb0998e6a1e21bed2b8c4.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0027_lambda keyword with do block" +input: |2- +<% content = lambda do %> + Content +<% end %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = lambda do " (location: (1:2)-(1:23)) + │ ├── tag_closing: "%>" (location: (1:23)-(1:25)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:25)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " end " (location: (3:2)-(3:7)) + │ └── tag_closing: "%>" (location: (3:7)-(3:9)) + │ + │ + └── @ HTMLTextNode (location: (3:9)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0028_lambda_keyword_with_do_block_and_params_fe9cd507d138aa98d210641671de0b17.txt b/test/snapshots/analyze/block_test/test_0028_lambda_keyword_with_do_block_and_params_fe9cd507d138aa98d210641671de0b17.txt new file mode 100644 index 000000000..223902380 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0028_lambda_keyword_with_do_block_and_params_fe9cd507d138aa98d210641671de0b17.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0028_lambda keyword with do block and params" +input: |2- +<% content = lambda do |x| %> + Content +<% end %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = lambda do |x| " (location: (1:2)-(1:27)) + │ ├── tag_closing: "%>" (location: (1:27)-(1:29)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:29)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:9)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " end " (location: (3:2)-(3:7)) + │ └── tag_closing: "%>" (location: (3:7)-(3:9)) + │ + │ + └── @ HTMLTextNode (location: (3:9)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0029_inline_stabby_lambda_with_do_end_in_single_tag_d6ae6032fea680b0f28282eb89556a84.txt b/test/snapshots/analyze/block_test/test_0029_inline_stabby_lambda_with_do_end_in_single_tag_d6ae6032fea680b0f28282eb89556a84.txt new file mode 100644 index 000000000..ed1d84994 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0029_inline_stabby_lambda_with_do_end_in_single_tag_d6ae6032fea680b0f28282eb89556a84.txt @@ -0,0 +1,16 @@ +--- +source: "Analyze::BlockTest#test_0029_inline stabby lambda with do/end in single tag" +input: |2- +<% content = -> do; end %> +--- +@ DocumentNode (location: (1:0)-(2:0)) +└── children: (2 items) + ├── @ ERBContentNode (location: (1:0)-(1:26)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = -> do; end " (location: (1:2)-(1:24)) + │ ├── tag_closing: "%>" (location: (1:24)-(1:26)) + │ ├── parsed: true + │ └── valid: true + │ + └── @ HTMLTextNode (location: (1:26)-(2:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0030_inline_lambda_keyword_with_do_end_in_single_tag_54c06beb62800538f64bb1d77354f106.txt b/test/snapshots/analyze/block_test/test_0030_inline_lambda_keyword_with_do_end_in_single_tag_54c06beb62800538f64bb1d77354f106.txt new file mode 100644 index 000000000..a5a853945 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0030_inline_lambda_keyword_with_do_end_in_single_tag_54c06beb62800538f64bb1d77354f106.txt @@ -0,0 +1,16 @@ +--- +source: "Analyze::BlockTest#test_0030_inline lambda keyword with do/end in single tag" +input: |2- +<% content = lambda do; end %> +--- +@ DocumentNode (location: (1:0)-(2:0)) +└── children: (2 items) + ├── @ ERBContentNode (location: (1:0)-(1:30)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = lambda do; end " (location: (1:2)-(1:28)) + │ ├── tag_closing: "%>" (location: (1:28)-(1:30)) + │ ├── parsed: true + │ └── valid: true + │ + └── @ HTMLTextNode (location: (1:30)-(2:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0031_stabby_lambda_with_brace_block_1946126146ae485822c40d7b0e816743.txt b/test/snapshots/analyze/block_test/test_0031_stabby_lambda_with_brace_block_1946126146ae485822c40d7b0e816743.txt new file mode 100644 index 000000000..6debd2969 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0031_stabby_lambda_with_brace_block_1946126146ae485822c40d7b0e816743.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0031_stabby lambda with brace block" +input: |2- +<% content = -> { %> + Content +<% } %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:7)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = -> { " (location: (1:2)-(1:18)) + │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:20)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:7)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " } " (location: (3:2)-(3:5)) + │ └── tag_closing: "%>" (location: (3:5)-(3:7)) + │ + │ + └── @ HTMLTextNode (location: (3:7)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0032_lambda_keyword_with_brace_block_7ab1eeb026e4a5427166556a3e7a49c2.txt b/test/snapshots/analyze/block_test/test_0032_lambda_keyword_with_brace_block_7ab1eeb026e4a5427166556a3e7a49c2.txt new file mode 100644 index 000000000..b1484c064 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0032_lambda_keyword_with_brace_block_7ab1eeb026e4a5427166556a3e7a49c2.txt @@ -0,0 +1,26 @@ +--- +source: "Analyze::BlockTest#test_0032_lambda keyword with brace block" +input: |2- +<% content = lambda { %> + Content +<% } %> +--- +@ DocumentNode (location: (1:0)-(4:0)) +└── children: (2 items) + ├── @ ERBBlockNode (location: (1:0)-(3:7)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " content = lambda { " (location: (1:2)-(1:22)) + │ ├── tag_closing: "%>" (location: (1:22)-(1:24)) + │ ├── body: (1 item) + │ │ └── @ HTMLTextNode (location: (1:24)-(3:0)) + │ │ └── content: "\n Content\n" + │ │ + │ └── end_node: + │ └── @ ERBEndNode (location: (3:0)-(3:7)) + │ ├── tag_opening: "<%" (location: (3:0)-(3:2)) + │ ├── content: " } " (location: (3:2)-(3:5)) + │ └── tag_closing: "%>" (location: (3:5)-(3:7)) + │ + │ + └── @ HTMLTextNode (location: (3:7)-(4:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0033_unclosed_stabby_lambda_with_do_block_7d6f7e59ef4d8235f30fd5db189432ee.txt b/test/snapshots/analyze/block_test/test_0033_unclosed_stabby_lambda_with_do_block_7d6f7e59ef4d8235f30fd5db189432ee.txt new file mode 100644 index 000000000..7d303692f --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0033_unclosed_stabby_lambda_with_do_block_7d6f7e59ef4d8235f30fd5db189432ee.txt @@ -0,0 +1,35 @@ +--- +source: "Analyze::BlockTest#test_0033_unclosed stabby lambda with do block" +input: |2- +<% content = -> do %> + Content +--- +@ DocumentNode (location: (1:0)-(3:0)) +├── errors: (2 errors) +│ ├── @ RubyParseError (location: (2:9)-(3:0)) +│ │ ├── message: "unexpected_token_close_context: unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── error_message: "unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── diagnostic_id: "unexpected_token_close_context" +│ │ └── level: "syntax" +│ │ +│ └── @ RubyParseError (location: (1:13)-(1:15)) +│ ├── message: "lambda_term_end: expected a lambda block beginning with `do` to end with `end`" +│ ├── error_message: "expected a lambda block beginning with `do` to end with `end`" +│ ├── diagnostic_id: "lambda_term_end" +│ └── level: "syntax" +│ +└── children: (1 item) + └── @ ERBBlockNode (location: (1:0)-(3:0)) + ├── errors: (1 error) + │ └── @ MissingERBEndTagError (location: (1:0)-(1:21)) + │ ├── message: "ERB block started here but never closed with an end tag. The end tag may be in a different scope." + │ └── keyword: "ERB block" + │ + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " content = -> do " (location: (1:2)-(1:19)) + ├── tag_closing: "%>" (location: (1:19)-(1:21)) + ├── body: (1 item) + │ └── @ HTMLTextNode (location: (1:21)-(3:0)) + │ └── content: "\n Content\n" + │ + └── end_node: ∅ \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0034_unclosed_stabby_lambda_with_brace_block_b43d364322f8991b6b31038fb151087c.txt b/test/snapshots/analyze/block_test/test_0034_unclosed_stabby_lambda_with_brace_block_b43d364322f8991b6b31038fb151087c.txt new file mode 100644 index 000000000..ba3299d78 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0034_unclosed_stabby_lambda_with_brace_block_b43d364322f8991b6b31038fb151087c.txt @@ -0,0 +1,35 @@ +--- +source: "Analyze::BlockTest#test_0034_unclosed stabby lambda with brace block" +input: |2- +<% content = -> { %> + Content +--- +@ DocumentNode (location: (1:0)-(3:0)) +├── errors: (2 errors) +│ ├── @ RubyParseError (location: (2:9)-(3:0)) +│ │ ├── message: "unexpected_token_close_context: unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── error_message: "unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── diagnostic_id: "unexpected_token_close_context" +│ │ └── level: "syntax" +│ │ +│ └── @ RubyParseError (location: (1:16)-(1:17)) +│ ├── message: "lambda_term_brace: expected a lambda block beginning with `{` to end with `}`" +│ ├── error_message: "expected a lambda block beginning with `{` to end with `}`" +│ ├── diagnostic_id: "lambda_term_brace" +│ └── level: "syntax" +│ +└── children: (1 item) + └── @ ERBBlockNode (location: (1:0)-(3:0)) + ├── errors: (1 error) + │ └── @ MissingERBEndTagError (location: (1:0)-(1:20)) + │ ├── message: "ERB block started here but never closed with an end tag. The end tag may be in a different scope." + │ └── keyword: "ERB block" + │ + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " content = -> { " (location: (1:2)-(1:18)) + ├── tag_closing: "%>" (location: (1:18)-(1:20)) + ├── body: (1 item) + │ └── @ HTMLTextNode (location: (1:20)-(3:0)) + │ └── content: "\n Content\n" + │ + └── end_node: ∅ \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0035_unclosed_lambda_keyword_with_do_block_0f1b91582217c885699c38df65576d83.txt b/test/snapshots/analyze/block_test/test_0035_unclosed_lambda_keyword_with_do_block_0f1b91582217c885699c38df65576d83.txt new file mode 100644 index 000000000..ae79b2186 --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0035_unclosed_lambda_keyword_with_do_block_0f1b91582217c885699c38df65576d83.txt @@ -0,0 +1,35 @@ +--- +source: "Analyze::BlockTest#test_0035_unclosed lambda keyword with do block" +input: |2- +<% content = lambda do %> + Content +--- +@ DocumentNode (location: (1:0)-(3:0)) +├── errors: (2 errors) +│ ├── @ RubyParseError (location: (2:9)-(3:0)) +│ │ ├── message: "unexpected_token_close_context: unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── error_message: "unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── diagnostic_id: "unexpected_token_close_context" +│ │ └── level: "syntax" +│ │ +│ └── @ RubyParseError (location: (1:20)-(1:22)) +│ ├── message: "block_term_end: expected a block beginning with `do` to end with `end`" +│ ├── error_message: "expected a block beginning with `do` to end with `end`" +│ ├── diagnostic_id: "block_term_end" +│ └── level: "syntax" +│ +└── children: (1 item) + └── @ ERBBlockNode (location: (1:0)-(3:0)) + ├── errors: (1 error) + │ └── @ MissingERBEndTagError (location: (1:0)-(1:25)) + │ ├── message: "ERB block started here but never closed with an end tag. The end tag may be in a different scope." + │ └── keyword: "ERB block" + │ + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " content = lambda do " (location: (1:2)-(1:23)) + ├── tag_closing: "%>" (location: (1:23)-(1:25)) + ├── body: (1 item) + │ └── @ HTMLTextNode (location: (1:25)-(3:0)) + │ └── content: "\n Content\n" + │ + └── end_node: ∅ \ No newline at end of file diff --git a/test/snapshots/analyze/block_test/test_0036_unclosed_lambda_keyword_with_brace_block_64d15f18add0fc26b768522cd37c8e25.txt b/test/snapshots/analyze/block_test/test_0036_unclosed_lambda_keyword_with_brace_block_64d15f18add0fc26b768522cd37c8e25.txt new file mode 100644 index 000000000..cf27e431a --- /dev/null +++ b/test/snapshots/analyze/block_test/test_0036_unclosed_lambda_keyword_with_brace_block_64d15f18add0fc26b768522cd37c8e25.txt @@ -0,0 +1,35 @@ +--- +source: "Analyze::BlockTest#test_0036_unclosed lambda keyword with brace block" +input: |2- +<% content = lambda { %> + Content +--- +@ DocumentNode (location: (1:0)-(3:0)) +├── errors: (2 errors) +│ ├── @ RubyParseError (location: (2:9)-(3:0)) +│ │ ├── message: "unexpected_token_close_context: unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── error_message: "unexpected end-of-input, assuming it is closing the parent top level context" +│ │ ├── diagnostic_id: "unexpected_token_close_context" +│ │ └── level: "syntax" +│ │ +│ └── @ RubyParseError (location: (1:20)-(1:21)) +│ ├── message: "block_term_brace: expected a block beginning with `{` to end with `}`" +│ ├── error_message: "expected a block beginning with `{` to end with `}`" +│ ├── diagnostic_id: "block_term_brace" +│ └── level: "syntax" +│ +└── children: (1 item) + └── @ ERBBlockNode (location: (1:0)-(3:0)) + ├── errors: (1 error) + │ └── @ MissingERBEndTagError (location: (1:0)-(1:24)) + │ ├── message: "ERB block started here but never closed with an end tag. The end tag may be in a different scope." + │ └── keyword: "ERB block" + │ + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " content = lambda { " (location: (1:2)-(1:22)) + ├── tag_closing: "%>" (location: (1:22)-(1:24)) + ├── body: (1 item) + │ └── @ HTMLTextNode (location: (1:24)-(3:0)) + │ └── content: "\n Content\n" + │ + └── end_node: ∅ \ No newline at end of file