Skip to content

Commit

Permalink
Support ruby 3.3 by handling yield
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwessman committed Apr 23, 2024
1 parent e8d9d95 commit af1c273
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 7 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
- "3.0"
- "3.1"
- "3.2"
- "3.3"
name: CI
runs-on: ubuntu-latest
env:
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby 3.2.3
ruby 3.3.0
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

- Support Ruby 3.3 by handling yield in ERB specifically

## [0.11.0] - 2024-04-23

- ErbContent now has its value as child_nodes instead of empty array.
Expand Down
9 changes: 7 additions & 2 deletions lib/syntax_tree/erb/format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ def visit_erb_close(node)
visit(node.closing)
end

def visit_erb_yield(node)
q.text("yield")
end

# Visit an ErbEnd node.
def visit_erb_end(node)
visit(node.opening_tag)
Expand Down Expand Up @@ -169,9 +173,10 @@ def format_statement(statement)

formatter.format(statement)
formatter.flush
rows = formatter.output.join.split("\n")

output_rows(rows)
formatted = formatter.output.join.gsub(SyntaxTree::ERB::ErbYield::PLACEHOLDER, "yield")

output_rows(formatted.split("\n"))
end

def output_rows(rows)
Expand Down
32 changes: 28 additions & 4 deletions lib/syntax_tree/erb/nodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,10 @@ def prepare_content(content)
ErbContent.new(value: content)
end
rescue SyntaxTree::Parser::ParseError
# Try to add the keyword to see if it parses
result = ErbContent.new(value: [keyword, *content])
@keyword = nil
# Try to add the keyword to see if it parses
result = ErbContent.new(value: [keyword, *content])
@keyword = nil

result
end
end
Expand Down Expand Up @@ -489,7 +490,15 @@ class ErbContent < Node
def initialize(value:)
if value.is_a?(Array)
value =
value.map { |token| token.is_a?(Token) ? token.value : token }.join
value.map do |token|
if token.is_a?(Token)
token.value
elsif token.is_a?(ErbYield)
ErbYield::PLACEHOLDER
else
token
end
end.join
end
@value = SyntaxTree.parse(value.strip)
end
Expand Down Expand Up @@ -518,6 +527,21 @@ def deconstruct_keys(keys)
end
end

class ErbYield < Element
PLACEHOLDER = "qqqqy"
def initialize(new_line:, location:)
super(new_line: new_line, location: location)
end

def accept(visitor)
visitor.visit_erb_yield(self)
end

def child_nodes
[]
end
end

# An HtmlAttribute is a key-value pair within a tag. It contains the key, the
# equals sign, and the value.
class HtmlAttribute < Node
Expand Down
14 changes: 14 additions & 0 deletions lib/syntax_tree/erb/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ def make_tokens
when /\A-?%>/
enum.yield :erb_close, $&, index, line
state.pop
when /\Ayield\b/
enum.yield :erb_yield, $&, index, line
when /\A[\p{L}\w]*\b/
# Split by word boundary while parsing the code
# This allows us to separate what_to_do vs do
Expand Down Expand Up @@ -648,6 +650,7 @@ def parse_until_erb_close
result =
atleast do
maybe { parse_erb_do_close } || maybe { parse_erb_close } ||
maybe { parse_erb_yield } ||
maybe { consume(:erb_code) }
end

Expand Down Expand Up @@ -701,6 +704,17 @@ def parse_erb_do_close
)
end

def parse_erb_yield
token = consume(:erb_yield)

new_line = maybe { parse_new_line }

ErbYield.new(
location: token.location,
new_line: new_line,
)
end

def parse_html_string
opening =
maybe { consume(:string_open_double_quote) } ||
Expand Down
4 changes: 4 additions & 0 deletions lib/syntax_tree/erb/pretty_print.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ def visit_erb_do_close(node)
visit_node("erb_do_close", node)
end

def visit_erb_yield(node)
visit_node("erb_yield", node)
end

# Visit a Doctype node.
def visit_doctype(node)
visit_node("doctype", node)
Expand Down

0 comments on commit af1c273

Please sign in to comment.