mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-26 13:45:13 -07:00
Parsing for if statements
This commit is contained in:
+13
-7
@@ -29,11 +29,12 @@ module Liquid
|
|||||||
'[' => :open_square,
|
'[' => :open_square,
|
||||||
']' => :close_square
|
']' => :close_square
|
||||||
}
|
}
|
||||||
IDENTIFIER = /[\w\-]+/
|
IDENTIFIER = /[\w\-?]+/
|
||||||
SINGLE_STRING_LITERAL = /'[^\']*'/
|
SINGLE_STRING_LITERAL = /'[^\']*'/
|
||||||
DOUBLE_STRING_LITERAL = /"[^\"]*"/
|
DOUBLE_STRING_LITERAL = /"[^\"]*"/
|
||||||
INTEGER_LITERAL = /-?\d+/
|
INTEGER_LITERAL = /-?\d+/
|
||||||
FLOAT_LITERAL = /-?\d+(?:\.\d+)?/
|
FLOAT_LITERAL = /-?\d+(?:\.\d+)?/
|
||||||
|
COMPARISON_OPERATOR = /==|!=|<>|<=?|>=?|contains/
|
||||||
|
|
||||||
def initialize(input)
|
def initialize(input)
|
||||||
@ss = StringScanner.new(input)
|
@ss = StringScanner.new(input)
|
||||||
@@ -57,21 +58,26 @@ module Liquid
|
|||||||
return if @ss.eos?
|
return if @ss.eos?
|
||||||
|
|
||||||
case
|
case
|
||||||
|
when t = @ss.scan(COMPARISON_OPERATOR) then Token[:comparison, t]
|
||||||
when t = @ss.scan(IDENTIFIER) then Token[:id, t]
|
when t = @ss.scan(IDENTIFIER) then Token[:id, t]
|
||||||
when t = @ss.scan(SINGLE_STRING_LITERAL) then Token[:string, t]
|
when t = @ss.scan(SINGLE_STRING_LITERAL) then Token[:string, t]
|
||||||
when t = @ss.scan(DOUBLE_STRING_LITERAL) then Token[:string, t]
|
when t = @ss.scan(DOUBLE_STRING_LITERAL) then Token[:string, t]
|
||||||
when t = @ss.scan(INTEGER_LITERAL) then Token[:integer, t]
|
when t = @ss.scan(INTEGER_LITERAL) then Token[:integer, t]
|
||||||
when t = @ss.scan(FLOAT_LITERAL) then Token[:float, t]
|
when t = @ss.scan(FLOAT_LITERAL) then Token[:float, t]
|
||||||
else
|
else
|
||||||
c = @ss.getch
|
lex_specials
|
||||||
if s = SPECIALS[c]
|
|
||||||
return Token[s,c]
|
|
||||||
end
|
|
||||||
|
|
||||||
raise SyntaxError, "Unexpected character #{c}."
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def lex_specials
|
||||||
|
c = @ss.getch
|
||||||
|
if s = SPECIALS[c]
|
||||||
|
return Token[s,c]
|
||||||
|
end
|
||||||
|
|
||||||
|
raise SyntaxError, "Unexpected character #{c}."
|
||||||
|
end
|
||||||
|
|
||||||
def consume_whitespace
|
def consume_whitespace
|
||||||
@ss.skip(/\s*/)
|
@ss.skip(/\s*/)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ module Liquid
|
|||||||
block = if tag == 'else'
|
block = if tag == 'else'
|
||||||
ElseCondition.new
|
ElseCondition.new
|
||||||
else
|
else
|
||||||
old_parse(markup)
|
parse_condition(markup)
|
||||||
end
|
end
|
||||||
|
|
||||||
@blocks.push(block)
|
@blocks.push(block)
|
||||||
@@ -81,12 +81,19 @@ module Liquid
|
|||||||
new_cond.send(op.to_sym, condition)
|
new_cond.send(op.to_sym, condition)
|
||||||
condition = new_cond
|
condition = new_cond
|
||||||
end
|
end
|
||||||
|
p.consume(:end_of_string)
|
||||||
|
|
||||||
condition
|
condition
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_comparison(p)
|
def parse_comparison(p)
|
||||||
|
a = p.expression
|
||||||
|
if op = p.consume?(:comparison)
|
||||||
|
b = p.expression
|
||||||
|
Condition.new(a, op, b)
|
||||||
|
else
|
||||||
|
Condition.new(a)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,8 @@ class ErrorHandlingTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_unrecognized_operator
|
def test_unrecognized_operator
|
||||||
assert_nothing_raised do
|
assert_raise(SyntaxError) do
|
||||||
template = Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
|
Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
|
||||||
assert_equal ' Liquid error: Unknown operator =! ', template.render
|
|
||||||
assert_equal 1, template.errors.size
|
|
||||||
assert_equal Liquid::ArgumentError, template.errors.first.class
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -40,15 +40,20 @@ class ParsingQuirksTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_meaningless_parens
|
def test_meaningless_parens
|
||||||
assigns = {'b' => 'bar', 'c' => 'baz'}
|
assert_raise(SyntaxError) do
|
||||||
markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
|
markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
|
||||||
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}", assigns)
|
Template.parse("{% if #{markup} %} YES {% endif %}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_unexpected_characters_silently_eat_logic
|
def test_unexpected_characters_silently_eat_logic
|
||||||
markup = "true && false"
|
assert_raise(SyntaxError) do
|
||||||
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}")
|
markup = "true && false"
|
||||||
markup = "false || true"
|
Template.parse("{% if #{markup} %} YES {% endif %}")
|
||||||
assert_template_result('',"{% if #{markup} %} YES {% endif %}")
|
end
|
||||||
|
assert_raise(SyntaxError) do
|
||||||
|
markup = "false || true"
|
||||||
|
Template.parse("{% if #{markup} %} YES {% endif %}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end # ParsingQuirksTest
|
end # ParsingQuirksTest
|
||||||
|
|||||||
Reference in New Issue
Block a user