Skip to content

Commit 2e5b674

Browse files
authored
Respect disable_liquid_c_nodes when parsing expressions (#154)
1 parent 6782f03 commit 2e5b674

3 files changed

Lines changed: 37 additions & 12 deletions

File tree

ext/liquid_c/expression.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ static VALUE internal_expression_parse(parser_t *p)
6262

6363
static VALUE expression_strict_parse(VALUE klass, VALUE markup)
6464
{
65+
if (NIL_P(markup))
66+
return Qnil;
67+
6568
StringValue(markup);
6669
char *start = RSTRING_PTR(markup);
6770

lib/liquid/c.rb

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def new_block_body
7070
end
7171

7272
alias_method :ruby_new_tokenizer, :new_tokenizer
73-
7473
def new_tokenizer(source, start_line_number: nil, for_liquid_tag: false)
7574
unless liquid_c_nodes_disabled?
7675
source = source.to_s.to_str
@@ -85,6 +84,14 @@ def new_tokenizer(source, start_line_number: nil, for_liquid_tag: false)
8584
ruby_new_tokenizer(source, start_line_number: start_line_number, for_liquid_tag: for_liquid_tag)
8685
end
8786

87+
def parse_expression(markup)
88+
if liquid_c_nodes_disabled?
89+
Liquid::Expression.ruby_parse(markup)
90+
else
91+
Liquid::C::Expression.lax_parse(markup)
92+
end
93+
end
94+
8895
# @api private
8996
def liquid_c_nodes_disabled?
9097
# Liquid::Profiler exposes the internal parse tree that we don't want to build when
@@ -195,21 +202,22 @@ def arg_exc_to_liquid_exc(argument_error)
195202
end
196203
end
197204

205+
Liquid::C::Expression.class_eval do
206+
class << self
207+
def lax_parse(markup)
208+
strict_parse(markup)
209+
rescue Liquid::SyntaxError
210+
Liquid::Expression.ruby_parse(markup)
211+
end
212+
end
213+
end
214+
198215
Liquid::Expression.class_eval do
199216
class << self
200217
alias_method :ruby_parse, :parse
201218

202-
def parse(markup)
203-
return nil unless markup
204-
205-
if Liquid::C.enabled
206-
begin
207-
return Liquid::C::Expression.strict_parse(markup)
208-
rescue Liquid::SyntaxError
209-
# no-op
210-
end
211-
end
212-
ruby_parse(markup)
219+
def c_parse(markup)
220+
Liquid::C::Expression.lax_parse(markup)
213221
end
214222
end
215223
end
@@ -251,10 +259,12 @@ def enabled=(value)
251259
Liquid::Context.send(:alias_method, :evaluate, :c_evaluate)
252260
Liquid::Context.send(:alias_method, :find_variable, :c_find_variable_kwarg)
253261
Liquid::Context.send(:alias_method, :strict_variables=, :c_strict_variables=)
262+
Liquid::Expression.singleton_class.send(:alias_method, :parse, :c_parse)
254263
else
255264
Liquid::Context.send(:alias_method, :evaluate, :ruby_evaluate)
256265
Liquid::Context.send(:alias_method, :find_variable, :ruby_find_variable)
257266
Liquid::Context.send(:alias_method, :strict_variables=, :ruby_strict_variables=)
267+
Liquid::Expression.singleton_class.send(:alias_method, :parse, :ruby_parse)
258268
end
259269
end
260270
end

test/unit/expression_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ def test_disassemble_int16
157157
ASM
158158
end
159159

160+
def test_disable_c_nodes
161+
context = Liquid::Context.new({ "x" => 123 })
162+
163+
expr = Liquid::ParseContext.new.parse_expression('x')
164+
assert_instance_of(Liquid::C::Expression, expr)
165+
assert_equal(123, context.evaluate(expr))
166+
167+
expr = Liquid::ParseContext.new(disable_liquid_c_nodes: true).parse_expression('x')
168+
assert_instance_of(Liquid::VariableLookup, expr)
169+
assert_equal(123, context.evaluate(expr))
170+
end
171+
160172
private
161173

162174
class ReturnKeyDrop < Liquid::Drop

0 commit comments

Comments
 (0)