mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-18 18:30:40 -07:00
Optimize filter invocation
This commit is contained in:
@@ -186,8 +186,8 @@ module Liquid
|
||||
end
|
||||
|
||||
def create_variable(token, parse_context)
|
||||
token.scan(ContentOfVariable) do |content|
|
||||
markup = content.first
|
||||
if token =~ ContentOfVariable
|
||||
markup = Regexp.last_match(1)
|
||||
return Variable.new(markup, parse_context)
|
||||
end
|
||||
raise_missing_variable_terminator(token, parse_context)
|
||||
|
||||
@@ -93,8 +93,13 @@ module Liquid
|
||||
exception_renderer.call(e).to_s
|
||||
end
|
||||
|
||||
def invoke(method, *args)
|
||||
strainer.invoke(method, *args).to_liquid
|
||||
def invoke(method, input, *args)
|
||||
strainer.invoke(method, input, *args).to_liquid
|
||||
end
|
||||
|
||||
# @api private
|
||||
def invoke_filter(method, input, args)
|
||||
strainer.invoke_filter(method, input, args).to_liquid
|
||||
end
|
||||
|
||||
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
|
||||
|
||||
@@ -24,11 +24,11 @@ module Liquid
|
||||
|
||||
include(filter)
|
||||
|
||||
filter_methods.merge(filter.public_instance_methods.map(&:to_s))
|
||||
filter_methods.merge(filter.public_instance_methods)
|
||||
end
|
||||
|
||||
def invokable?(method)
|
||||
filter_methods.include?(method.to_s)
|
||||
filter_methods.include?(method.to_sym)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -38,13 +38,18 @@ module Liquid
|
||||
end
|
||||
end
|
||||
|
||||
def invoke(method, *args)
|
||||
def invoke(method, input, *args)
|
||||
invoke_filter(method.to_sym, input, args)
|
||||
end
|
||||
|
||||
# @api private
|
||||
def invoke_filter(method, input, args)
|
||||
if self.class.invokable?(method)
|
||||
send(method, *args)
|
||||
send(method, input, *args)
|
||||
elsif @context.strict_filters
|
||||
raise Liquid::UndefinedFilter, "undefined filter #{method}"
|
||||
else
|
||||
args.first
|
||||
input
|
||||
end
|
||||
rescue ::ArgumentError => e
|
||||
raise Liquid::ArgumentError, e.message, e.backtrace
|
||||
|
||||
+42
-11
@@ -18,7 +18,7 @@ module Liquid
|
||||
JustTagAttributes = /\A#{TagAttributes}\z/o
|
||||
MarkupWithQuotedFragment = /(#{QuotedFragment})(.*)/om
|
||||
|
||||
attr_accessor :filters, :name, :line_number
|
||||
attr_accessor :name, :line_number
|
||||
attr_reader :parse_context
|
||||
alias_method :options, :parse_context
|
||||
|
||||
@@ -81,12 +81,15 @@ module Liquid
|
||||
end
|
||||
|
||||
def render(context)
|
||||
obj = @filters.inject(context.evaluate(@name)) do |output, (filter_name, filter_args, filter_kwargs)|
|
||||
filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
||||
context.invoke(filter_name, output, *filter_args)
|
||||
result = context.evaluate(@name)
|
||||
@filters.each do |filter_name, constant_args, filter_args, filter_kwargs|
|
||||
unless constant_args
|
||||
filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
||||
end
|
||||
result = context.invoke_filter(filter_name, result, filter_args)
|
||||
end
|
||||
|
||||
context.apply_global_filter(obj)
|
||||
context.apply_global_filter(result)
|
||||
end
|
||||
|
||||
def render_to_output_buffer(context, output)
|
||||
@@ -110,21 +113,49 @@ module Liquid
|
||||
[]
|
||||
end
|
||||
|
||||
def filters
|
||||
@filters.map do |filter_name, constant_args, *filter_args_and_kwargs|
|
||||
filter_name = filter_name.to_s
|
||||
if constant_args
|
||||
filter_args = filter_args_and_kwargs.first
|
||||
if filter_args.last.is_a?(Hash)
|
||||
filter_args = filter_args.dup
|
||||
[filter_name, filter_args, filter_args.pop]
|
||||
else
|
||||
[filter_name, *filter_args_and_kwargs]
|
||||
end
|
||||
else
|
||||
[filter_name, *filter_args_and_kwargs]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_filter_expressions(filter_name, unparsed_args)
|
||||
filter_args = []
|
||||
constant_args = true
|
||||
filter_args = []
|
||||
keyword_args = nil
|
||||
unparsed_args.each do |a|
|
||||
if (matches = a.match(JustTagAttributes))
|
||||
keyword_args ||= {}
|
||||
keyword_args[matches[1]] = Expression.parse(matches[2])
|
||||
keyword_args ||= {}
|
||||
expression = Expression.parse(matches[2])
|
||||
constant_args &&= !expression.is_a?(VariableLookup)
|
||||
keyword_args[matches[1]] = expression
|
||||
else
|
||||
filter_args << Expression.parse(a)
|
||||
expression = Expression.parse(a)
|
||||
constant_args &&= !expression.is_a?(VariableLookup)
|
||||
filter_args << expression
|
||||
end
|
||||
end
|
||||
result = [filter_name.to_sym, constant_args, filter_args]
|
||||
if keyword_args
|
||||
if constant_args
|
||||
filter_args << keyword_args
|
||||
else
|
||||
result << keyword_args
|
||||
end
|
||||
end
|
||||
result = [filter_name, filter_args]
|
||||
result << keyword_args if keyword_args
|
||||
result
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user