Address comments

This commit is contained in:
Peter Zhu
2020-11-12 16:14:33 -05:00
parent 6d19a56ef3
commit 38600338cf
9 changed files with 104 additions and 84 deletions
+8
View File
@@ -49,6 +49,14 @@ module Liquid
@@method_literals[markup] || parse_context.parse_expression(markup) @@method_literals[markup] || parse_context.parse_expression(markup)
end end
def self.strict_parse_expression(parse_context, p)
if p.look(:id) && !p.look(:dot, 1) && !p.look(:open_square, 1)
parse_expression(parse_context, p.consume)
else
p.expression
end
end
attr_reader :attachment, :child_condition attr_reader :attachment, :child_condition
attr_accessor :left, :operator, :right attr_accessor :left, :operator, :right
+3 -6
View File
@@ -60,18 +60,15 @@ module Liquid
when :string when :string
consume[1..-2] consume[1..-2]
when :number when :number
Expression.parse(consume) num_str = consume
num_str.include?('.') ? num_str.to_f : num_str.to_i
when :open_round when :open_round
consume consume
first = expression first = expression
consume(:dotdot) consume(:dotdot)
last = expression last = expression
consume(:close_round) consume(:close_round)
if first.respond_to?(:evaluate) || last.respond_to?(:evaluate) RangeLookup.build(first, last)
RangeLookup.new(first, last)
else
first.to_i..last.to_i
end
else else
raise SyntaxError, "#{token} is not a valid expression" raise SyntaxError, "#{token} is not a valid expression"
end end
+11 -7
View File
@@ -5,6 +5,10 @@ module Liquid
def self.parse(start_markup, end_markup) def self.parse(start_markup, end_markup)
start_obj = Expression.parse(start_markup) start_obj = Expression.parse(start_markup)
end_obj = Expression.parse(end_markup) end_obj = Expression.parse(end_markup)
build(start_obj, end_obj)
end
def self.build(start_obj, end_obj)
if start_obj.respond_to?(:evaluate) || end_obj.respond_to?(:evaluate) if start_obj.respond_to?(:evaluate) || end_obj.respond_to?(:evaluate)
new(start_obj, end_obj) new(start_obj, end_obj)
else else
@@ -12,21 +16,21 @@ module Liquid
end end
end end
attr_reader :start_obj, :end_obj attr_reader :start_expr, :end_expr
def initialize(start_obj, end_obj) def initialize(start_expr, end_expr)
@start_obj = start_obj @start_expr = start_expr
@end_obj = end_obj @end_expr = end_expr
end end
def evaluate(context) def evaluate(context)
start_int = to_integer(context.evaluate(@start_obj)) start_int = to_integer(context.evaluate(@start_expr))
end_int = to_integer(context.evaluate(@end_obj)) end_int = to_integer(context.evaluate(@end_expr))
start_int..end_int start_int..end_int
end end
def ==(other) def ==(other)
self.class == other.class && start_obj == other.start_obj && end_obj == other.end_obj self.class == other.class && start_expr == other.start_expr && end_expr == other.end_expr
end end
private private
+6 -10
View File
@@ -75,6 +75,10 @@ module Liquid
Condition.parse_expression(parse_context, markup) Condition.parse_expression(parse_context, markup)
end end
def strict_parse_expression(p)
Condition.strict_parse_expression(parse_context, p)
end
def lax_parse(markup) def lax_parse(markup)
expressions = markup.scan(ExpressionsAndOperators) expressions = markup.scan(ExpressionsAndOperators)
raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax
@@ -114,23 +118,15 @@ module Liquid
end end
def parse_comparison(p) def parse_comparison(p)
a = parse_operand_expression(p) a = strict_parse_expression(p)
if (op = p.consume?(:comparison)) if (op = p.consume?(:comparison))
b = parse_operand_expression(p) b = strict_parse_expression(p)
Condition.new(a, op, b) Condition.new(a, op, b)
else else
Condition.new(a) Condition.new(a)
end end
end end
def parse_operand_expression(p)
if p.look(:id) && !p.look(:dot, 1) && !p.look(:open_square, 1)
parse_expression(p.consume)
else
p.expression
end
end
class ParseTreeVisitor < Liquid::ParseTreeVisitor class ParseTreeVisitor < Liquid::ParseTreeVisitor
def children def children
@node.blocks @node.blocks
+1 -1
View File
@@ -69,7 +69,7 @@ module Liquid
while p.consume?(:pipe) while p.consume?(:pipe)
filtername = p.consume(:id) filtername = p.consume(:id)
filterargs = p.consume?(:colon) ? p.arguments : [[]] filterargs = p.consume?(:colon) ? p.arguments : [[]]
@filters << [filtername] + filterargs @filters << [filtername, *filterargs]
end end
p.consume(:end_of_string) p.consume(:end_of_string)
end end
+8 -4
View File
@@ -7,7 +7,8 @@ module Liquid
attr_reader :name, :lookups attr_reader :name, :lookups
def self.lax_parse(markup) class << self
def lax_parse(markup)
lookups = markup.scan(VariableParser) lookups = markup.scan(VariableParser)
name = lookups.shift name = lookups.shift
@@ -29,7 +30,7 @@ module Liquid
new(name, lookups, command_flags) new(name, lookups, command_flags)
end end
def self.strict_parse(p) def strict_parse(p)
if p.look(:id) if p.look(:id)
name = p.consume name = p.consume
else else
@@ -59,6 +60,9 @@ module Liquid
new(name, lookups, command_flags) new(name, lookups, command_flags)
end end
private :new
end
def initialize(name, lookups, command_flags) def initialize(name, lookups, command_flags)
@name = name @name = name
@lookups = lookups @lookups = lookups
@@ -112,9 +116,9 @@ module Liquid
lookups.each do |lookup| lookups.each do |lookup|
str += str +=
if lookup.instance_of?(String) if lookup.instance_of?(String)
'.' + lookup "['#{lookup}']"
else else
'[' + lookup.to_s + ']' "[#{lookup}]"
end end
end end
str str
+4 -2
View File
@@ -40,13 +40,15 @@ class ExpressionTest < Minitest::Test
private private
def parse_and_eval(markup, **assigns) def parse_and_eval(markup, **assigns)
expression =
if Liquid::Template.error_mode == :strict if Liquid::Template.error_mode == :strict
p = Liquid::Parser.new(markup) p = Liquid::Parser.new(markup)
p.expression p.expression
else else
expression = Liquid::Expression.parse(markup) Liquid::Expression.parse(markup)
end
context = Liquid::Context.new(assigns) context = Liquid::Context.new(assigns)
context.evaluate(expression) context.evaluate(expression)
end end
end end
end
+12 -6
View File
@@ -47,9 +47,9 @@ class ParserUnitTest < Minitest::Test
def test_expressions def test_expressions
p = Parser.new("hi.there hi?[5].there? hi.there.bob") p = Parser.new("hi.there hi?[5].there? hi.there.bob")
assert_equal(VariableLookup.new('hi', ['there'], 0), p.expression) assert_equal(VariableLookup.send(:new, 'hi', ['there'], 0), p.expression)
assert_equal(VariableLookup.new('hi?', [5, 'there?'], 0), p.expression) assert_equal(VariableLookup.send(:new, 'hi?', [5, 'there?'], 0), p.expression)
assert_equal(VariableLookup.new('hi', ['there', 'bob'], 0), p.expression) assert_equal(VariableLookup.send(:new, 'hi', ['there', 'bob'], 0), p.expression)
p = Parser.new("nil true false") p = Parser.new("nil true false")
assert_nil(p.expression) assert_nil(p.expression)
@@ -67,15 +67,21 @@ class ParserUnitTest < Minitest::Test
p = Parser.new("(5..7) (1.5..9.6) (young..old) (hi[5].wat..old)") p = Parser.new("(5..7) (1.5..9.6) (young..old) (hi[5].wat..old)")
assert_equal(5..7, p.expression) assert_equal(5..7, p.expression)
assert_equal(1..9, p.expression) assert_equal(1..9, p.expression)
assert_equal(RangeLookup.new(VariableLookup.new('young', [], 0), VariableLookup.new('old', [], 0)), p.expression) assert_equal(
assert_equal(RangeLookup.new(VariableLookup.new('hi', [5, "wat"], 0), VariableLookup.new('old', [], 0)), p.expression) RangeLookup.new(VariableLookup.send(:new, 'young', [], 0), VariableLookup.send(:new, 'old', [], 0)),
p.expression
)
assert_equal(
RangeLookup.new(VariableLookup.send(:new, 'hi', [5, "wat"], 0), VariableLookup.send(:new, 'old', [], 0)),
p.expression
)
end end
def test_arguments def test_arguments
p = Parser.new("filter: hi.there[5], keyarg: 7") p = Parser.new("filter: hi.there[5], keyarg: 7")
assert_equal('filter', p.consume(:id)) assert_equal('filter', p.consume(:id))
assert_equal(':', p.consume(:colon)) assert_equal(':', p.consume(:colon))
assert_equal([[VariableLookup.new("hi", ["there", 5], 0)], { "keyarg" => 7 }], p.arguments) assert_equal([[VariableLookup.send(:new, "hi", ["there", 5], 0)], { "keyarg" => 7 }], p.arguments)
end end
def test_invalid_expression def test_invalid_expression
+5 -2
View File
@@ -17,10 +17,13 @@ class VariableLookupUnitTest < Minitest::Test
def test_to_s def test_to_s
lookup = parse_variable_lookup('a.b.c') lookup = parse_variable_lookup('a.b.c')
assert_equal('a.b.c', lookup.to_s) assert_equal("a['b']['c']", lookup.to_s)
lookup = parse_variable_lookup('a[b.c].d') lookup = parse_variable_lookup('a[b.c].d')
assert_equal('a[b.c].d', lookup.to_s) assert_equal("a[b['c']]['d']", lookup.to_s)
lookup = parse_variable_lookup('a["foo.bar"].d')
assert_equal("a['foo.bar']['d']", lookup.to_s)
end end
private private