Extract Parser#variable_lookup out of Expression.parse

This commit is contained in:
Charles-P. Clermont
2026-01-26 16:52:17 -05:00
parent 8efcf7dd3a
commit 8b04c52ab2
3 changed files with 104 additions and 30 deletions
+72 -26
View File
@@ -50,6 +50,10 @@ module Liquid
def expression
token = @tokens[@p]
case token[0]
when :id
variable_lookup
when :open_square
unnamed_variable_lookup
when :string
string
when :number
@@ -68,6 +72,47 @@ module Liquid
consume(:string)[1..-2]
end
def variable_lookup
name = consume(:id)
lookups, command_flags = variable_lookups
if Expression::LITERALS.key?(name) && lookups.empty?
Expression::LITERALS[name]
else
VariableLookup.new(name, lookups, command_flags)
end
end
def unnamed_variable_lookup
name = indexed_lookup
lookups, command_flags = variable_lookups
VariableLookup.new(name, lookups, command_flags)
end
def expression_string
token = @tokens[@p]
case token[0]
when :id
str = consume
str << variable_lookups_string
when :open_square
str = consume.dup
str << expression_string
str << consume(:close_square)
str << variable_lookups_string
when :string, :number
consume
when :open_round
consume
first = expression_string
consume(:dotdot)
last = expression_string
consume(:close_round)
"(#{first}..#{last})"
else
raise SyntaxError, "#{token} is not a valid expression"
end
end
def argument_string
str = +""
# might be a keyword argument (identifier: expression)
@@ -79,7 +124,7 @@ module Liquid
str
end
def variable_lookups
def variable_lookups_string
str = +""
loop do
if look(:open_square)
@@ -96,31 +141,6 @@ module Liquid
str
end
def expression_string
token = @tokens[@p]
case token[0]
when :id
str = consume
str << variable_lookups
when :open_square
str = consume.dup
str << expression_string
str << consume(:close_square)
str << variable_lookups
when :string, :number
consume
when :open_round
consume
first = expression_string
consume(:dotdot)
last = expression_string
consume(:close_round)
"(#{first}..#{last})"
else
raise SyntaxError, "#{token} is not a valid expression"
end
end
# Assumes safe input. For cases where you need the string.
# Don't use this unless you're sure about what you're doing.
def unsafe_parse_expression(markup)
@@ -132,5 +152,31 @@ module Liquid
def parse_expression(markup)
Expression.parse(markup, @ss, @cache)
end
def variable_lookups
lookups = []
command_flags = 0
i = -1
loop do
i += 1
if look(:open_square)
lookups << indexed_lookup
elsif consume?(:dot)
lookup = consume(:id)
lookups << lookup
command_flags |= 1 << i if VariableLookup::COMMAND_METHODS.include?(lookup)
else
break
end
end
[lookups, command_flags]
end
def indexed_lookup
consume(:open_square)
expr = expression
consume(:close_square)
expr
end
end
end