Skip to content

Parser: Use location-based detection for ERB control types#871

Merged
marcoroth merged 1 commit into
mainfrom
parser-location-based-control-types
Nov 13, 2025
Merged

Parser: Use location-based detection for ERB control types#871
marcoroth merged 1 commit into
mainfrom
parser-location-based-control-types

Conversation

@marcoroth

@marcoroth marcoroth commented Nov 13, 2025

Copy link
Copy Markdown
Owner

This commit improves the parser's control type detection by comparing keyword locations instead of relying solely on AST node structure.

This template:

<% if value %>
<% elsif items.any? { |item| item.true? } %>
<% end %>

Now gets correctly parsed as:

@ DocumentNode (location: (1:0)-(3:9))
├── errors: []
└── children: (1 item)
    └── @ ERBIfNode (location: (1:0)-(3:9))
        ├── errors: []
        ├── tag_opening: "<%" (location: (1:0)-(1:2))
        ├── content: " if value " (location: (1:2)-(1:12))
        ├── tag_closing: "%>" (location: (1:12)-(1:14))
        ├── statements: (1 item)
           └── @ HTMLTextNode (location: (1:14)-(2:0))
               ├── errors: []└── content: "\n"
           
        ├── subsequent: 
           └── @ ERBIfNode (location: (2:0)-(3:0))
               ├── errors: []
               ├── tag_opening: "<%" (location: (2:0)-(2:2))├── content: " elsif items.any? { |item| item.true? } " (location: (2:2)-(2:42))
               ├── tag_closing: "%>" (location: (2:42)-(2:44))
               ├── statements: (1 item)
                  └── @ HTMLTextNode (location: (2:44)-(3:0))
                      ├── errors: []
                      └── content: "\n"
                  
               ├── subsequent: └── end_node: 
               
        └── end_node: 
            └── @ ERBEndNode (location: (3:0)-(3:9))
                ├── errors: []
                ├── tag_opening: "<%" (location: (3:0)-(3:2))
                ├── content: " end " (location: (3:2)-(3:7))
                └── tag_closing: "%>" (location: (3:7)-(3:9))

Previously the elsif was treated as ERBBlockNode causing the <% end %> to be consumed for the ERBBlockNode:

@ DocumentNode (location: (1:0)-(3:9))
├── errors: []
└── children: (1 item)
    └── @ ERBIfNode (location: (1:0)-(3:9))
        ├── errors: (1 item)
           └── @ MissingERBEndTagError (location: (1:0)-(1:14))
               ├── message: "`<% if %>` started here but never closed with an end tag. The end tag may be in a different scope."└── keyword: "`<% if %>`"
           
        ├── tag_opening: "<%" (location: (1:0)-(1:2))
        ├── content: " if value " (location: (1:2)-(1:12))
        ├── tag_closing: "%>" (location: (1:12)-(1:14))
        ├── statements: (2 items)
           ├── @ HTMLTextNode (location: (1:14)-(2:0))
              ├── errors: []
              └── content: "\n"
              
           └── @ ERBBlockNode (location: (2:0)-(3:9))
               ├── errors: []
               ├── tag_opening: "<%" (location: (2:0)-(2:2))├── content: " elsif items.any? { |item| item.true? } " (location: (2:2)-(2:42))
               ├── tag_closing: "%>" (location: (2:42)-(2:44))├── body: (1 item)
                  └── @ HTMLTextNode (location: (2:44)-(3:0))
                      ├── errors: []
                      └── content: "\n"
               └── end_node: 
                   └── @ ERBEndNode (location: (3:0)-(3:9))
                       ├── errors: []├── tag_opening: "<%" (location: (3:0)-(3:2))
                       ├── content: " end " (location: (3:2)-(3:7))└── tag_closing: "%>" (location: (3:7)-(3:9))
           
        ├── subsequent: 
        └── end_node: 

Resolves #857

@marcoroth marcoroth force-pushed the parser-location-based-control-types branch 2 times, most recently from a398ae4 to db4c1df Compare November 13, 2025 12:20
@marcoroth marcoroth force-pushed the parser-location-based-control-types branch from db4c1df to bde0ea5 Compare November 13, 2025 12:24
@marcoroth marcoroth merged commit 48b8962 into main Nov 13, 2025
24 checks passed
@marcoroth marcoroth deleted the parser-location-based-control-types branch November 13, 2025 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse error in Herb 0.8.0: if/elsif and inline block syntax

1 participant