Skip to content

Add yield ERB node#96

Merged
marcoroth merged 5 commits intomainfrom
yield
May 2, 2025
Merged

Add yield ERB node#96
marcoroth merged 5 commits intomainfrom
yield

Conversation

@marcoroth
Copy link
Owner

@marcoroth marcoroth commented May 1, 2025

This pull request introduces a new ERBYieldNode node so can more specifically target yield calls in ERB files, which usually need to be handled specially.

Since we extract the Ruby code from the source input we have a yield call in the a top-level of the Ruby source, which is not valid and results in a syntax error.

Given this file:

<head>
  <%= yield :head %>
</head>

We get this Ruby source:

      
      yield :head 
       

Which is not valid Ruby and results in this Prism error:

#<Prism::ParseError @type=:invalid_yield @message="Invalid yield" @location=#<Prism::Location @start_offset=13 @length=11 start_line=2> @level=:syntax>

Parse Tree (before):

@ DocumentNode (location: (1:0)-(3:7))
├── errors: (1 item)
│   └── @ RubyParseError (location: (2:6)-(2:11))
│       ├── message: "invalid_yield: Invalid yield"
│       ├── error_message: "Invalid yield"
│       ├── diagnostic_id: "invalid_yield"
│       └── level: "syntax"
│       
│   
└── children: (1 item)
    └── @ HTMLElementNode (location: (1:0)-(3:7))
        ├── errors: []
        ├── open_tag: 
        │   └── @ HTMLOpenTagNode (location: (1:0)-(1:6))
        │       ├── errors: []
        │       ├── tag_opening: "<" (location: (1:0)-(1:1))
        │       ├── tag_name: "head" (location: (1:1)-(1:5))
        │       ├── tag_closing: ">" (location: (1:5)-(1:6))
        │       ├── children: []
        │       └── is_void: false
        │       
        ├── tag_name: "head" (location: (1:1)-(1:5))
        ├── body: (3 items)
        │   ├── @ HTMLTextNode (location: (1:6)-(2:2))
        │   │   ├── errors: []
        │   │   └── content: "\n  "
        │   │   
        │   ├── @ ERBContentNode (location: (2:2)-(2:14))
        │   │   ├── errors: []
        │   │   ├── tag_opening: "<%=" (location: (2:2)-(2:5))
        │   │   ├── content: " yield " (location: (2:5)-(2:12))
        │   │   ├── tag_closing: "%>" (location: (2:12)-(2:14))
        │   │   ├── parsed: true
        │   │   └── valid: false
        │   │   
        │   └── @ HTMLTextNode (location: (2:14)-(3:0))
        │       ├── errors: []
        │       └── content: "\n"
        │       
        │   
        ├── close_tag: 
        │   └── @ HTMLCloseTagNode (location: (3:0)-(3:7))
        │       ├── errors: []
        │       ├── tag_opening: "</" (location: (3:0)-(3:2))
        │       ├── tag_name: "head" (location: (3:2)-(3:6))
        │       └── tag_closing: ">" (location: (3:6)-(3:7))
        │       
        └── is_void: false

Since yield calls are commonly used in ERB we are going to ignore the invalid_yield Prism parse error for now.

Parse Tree (after merging this pull request):

@ DocumentNode (location: (1:0)-(3:7))
├── errors: []
└── children: (1 item)
    └── @ HTMLElementNode (location: (1:0)-(3:7))
        ├── errors: []
        ├── open_tag: 
        │   └── @ HTMLOpenTagNode (location: (1:0)-(1:6))
        │       ├── errors: []
        │       ├── tag_opening: "<" (location: (1:0)-(1:1))
        │       ├── tag_name: "head" (location: (1:1)-(1:5))
        │       ├── tag_closing: ">" (location: (1:5)-(1:6))
        │       ├── children: []
        │       └── is_void: false
        │       
        ├── tag_name: "head" (location: (1:1)-(1:5))
        ├── body: (2 items)
        │   ├── @ HTMLTextNode (location: (1:6)-(2:2))
        │   │   ├── errors: []
        │   │   └── content: "\n  "
        │   │   
        │   └── @ ERBYieldNode (location: (2:2)-(3:0))
        │       ├── errors: []
        │       ├── tag_opening: "<%=" (location: (2:2)-(2:5))
        │       ├── content: " yield " (location: (2:5)-(2:12))
        │       └── tag_closing: "%>" (location: (2:12)-(2:14))
        │       
        │   
        ├── close_tag: 
        │   └── @ HTMLCloseTagNode (location: (3:0)-(3:7))
        │       ├── errors: []
        │       ├── tag_opening: "</" (location: (3:0)-(3:2))
        │       ├── tag_name: "head" (location: (3:2)-(3:6))
        │       └── tag_closing: ">" (location: (3:6)-(3:7))
        │       
        └── is_void: false

Which now includes the ERBYieldNode node and doesn't have the invalid_yield RubyParseError.

Resolves #90

@marcoroth marcoroth marked this pull request as ready for review May 2, 2025 10:46
@marcoroth marcoroth merged commit 92486f4 into main May 2, 2025
9 checks passed
@marcoroth marcoroth deleted the yield branch May 2, 2025 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

yield in ERB file returns a invalid_yield: Invalid yield

1 participant