liquid 4.0.0.rc3 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/History.md +93 -2
- data/README.md +8 -0
- data/lib/liquid.rb +18 -5
- data/lib/liquid/block.rb +47 -20
- data/lib/liquid/block_body.rb +190 -76
- data/lib/liquid/condition.rb +69 -29
- data/lib/liquid/context.rb +122 -76
- data/lib/liquid/document.rb +47 -9
- data/lib/liquid/drop.rb +4 -2
- data/lib/liquid/errors.rb +20 -25
- data/lib/liquid/expression.rb +30 -31
- data/lib/liquid/extensions.rb +8 -0
- data/lib/liquid/file_system.rb +6 -4
- data/lib/liquid/forloop_drop.rb +11 -4
- data/lib/liquid/i18n.rb +5 -3
- data/lib/liquid/interrupts.rb +3 -1
- data/lib/liquid/lexer.rb +35 -26
- data/lib/liquid/locales/en.yml +4 -2
- data/lib/liquid/parse_context.rb +17 -4
- data/lib/liquid/parse_tree_visitor.rb +42 -0
- data/lib/liquid/parser.rb +30 -18
- data/lib/liquid/parser_switching.rb +17 -3
- data/lib/liquid/partial_cache.rb +24 -0
- data/lib/liquid/profiler.rb +67 -86
- data/lib/liquid/profiler/hooks.rb +26 -14
- data/lib/liquid/range_lookup.rb +5 -3
- data/lib/liquid/register.rb +6 -0
- data/lib/liquid/resource_limits.rb +47 -8
- data/lib/liquid/standardfilters.rb +171 -57
- data/lib/liquid/static_registers.rb +44 -0
- data/lib/liquid/strainer_factory.rb +36 -0
- data/lib/liquid/strainer_template.rb +53 -0
- data/lib/liquid/tablerowloop_drop.rb +6 -4
- data/lib/liquid/tag.rb +28 -6
- data/lib/liquid/tag/disableable.rb +22 -0
- data/lib/liquid/tag/disabler.rb +21 -0
- data/lib/liquid/tags/assign.rb +32 -10
- data/lib/liquid/tags/break.rb +8 -3
- data/lib/liquid/tags/capture.rb +11 -8
- data/lib/liquid/tags/case.rb +41 -27
- data/lib/liquid/tags/comment.rb +5 -3
- data/lib/liquid/tags/continue.rb +8 -3
- data/lib/liquid/tags/cycle.rb +35 -16
- data/lib/liquid/tags/decrement.rb +6 -3
- data/lib/liquid/tags/echo.rb +26 -0
- data/lib/liquid/tags/for.rb +79 -47
- data/lib/liquid/tags/if.rb +53 -30
- data/lib/liquid/tags/ifchanged.rb +11 -10
- data/lib/liquid/tags/include.rb +42 -44
- data/lib/liquid/tags/increment.rb +7 -3
- data/lib/liquid/tags/raw.rb +14 -11
- data/lib/liquid/tags/render.rb +84 -0
- data/lib/liquid/tags/table_row.rb +32 -20
- data/lib/liquid/tags/unless.rb +15 -15
- data/lib/liquid/template.rb +60 -71
- data/lib/liquid/template_factory.rb +9 -0
- data/lib/liquid/tokenizer.rb +17 -9
- data/lib/liquid/usage.rb +8 -0
- data/lib/liquid/utils.rb +6 -4
- data/lib/liquid/variable.rb +55 -38
- data/lib/liquid/variable_lookup.rb +14 -6
- data/lib/liquid/version.rb +3 -1
- data/test/integration/assign_test.rb +74 -5
- data/test/integration/blank_test.rb +11 -8
- data/test/integration/block_test.rb +58 -0
- data/test/integration/capture_test.rb +18 -10
- data/test/integration/context_test.rb +608 -5
- data/test/integration/document_test.rb +4 -2
- data/test/integration/drop_test.rb +67 -83
- data/test/integration/error_handling_test.rb +90 -60
- data/test/integration/expression_test.rb +46 -0
- data/test/integration/filter_test.rb +53 -42
- data/test/integration/hash_ordering_test.rb +5 -3
- data/test/integration/output_test.rb +26 -24
- data/test/integration/parsing_quirks_test.rb +24 -8
- data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
- data/test/integration/security_test.rb +41 -18
- data/test/integration/standard_filter_test.rb +523 -205
- data/test/integration/tag/disableable_test.rb +59 -0
- data/test/integration/tag_test.rb +45 -0
- data/test/integration/tags/break_tag_test.rb +4 -2
- data/test/integration/tags/continue_tag_test.rb +4 -2
- data/test/integration/tags/echo_test.rb +13 -0
- data/test/integration/tags/for_tag_test.rb +109 -53
- data/test/integration/tags/if_else_tag_test.rb +5 -3
- data/test/integration/tags/include_tag_test.rb +83 -52
- data/test/integration/tags/increment_tag_test.rb +4 -2
- data/test/integration/tags/liquid_tag_test.rb +116 -0
- data/test/integration/tags/raw_tag_test.rb +14 -11
- data/test/integration/tags/render_tag_test.rb +213 -0
- data/test/integration/tags/standard_tag_test.rb +38 -31
- data/test/integration/tags/statements_test.rb +23 -21
- data/test/integration/tags/table_row_test.rb +2 -0
- data/test/integration/tags/unless_else_tag_test.rb +4 -2
- data/test/integration/template_test.rb +128 -121
- data/test/integration/trim_mode_test.rb +82 -44
- data/test/integration/variable_test.rb +46 -31
- data/test/test_helper.rb +75 -23
- data/test/unit/block_unit_test.rb +19 -24
- data/test/unit/condition_unit_test.rb +82 -72
- data/test/unit/file_system_unit_test.rb +6 -4
- data/test/unit/i18n_unit_test.rb +7 -5
- data/test/unit/lexer_unit_test.rb +12 -10
- data/test/unit/parse_tree_visitor_test.rb +247 -0
- data/test/unit/parser_unit_test.rb +37 -35
- data/test/unit/partial_cache_unit_test.rb +128 -0
- data/test/unit/regexp_unit_test.rb +17 -15
- data/test/unit/static_registers_unit_test.rb +156 -0
- data/test/unit/strainer_factory_unit_test.rb +100 -0
- data/test/unit/strainer_template_unit_test.rb +82 -0
- data/test/unit/tag_unit_test.rb +5 -3
- data/test/unit/tags/case_tag_unit_test.rb +3 -1
- data/test/unit/tags/for_tag_unit_test.rb +4 -2
- data/test/unit/tags/if_tag_unit_test.rb +3 -1
- data/test/unit/template_factory_unit_test.rb +12 -0
- data/test/unit/template_unit_test.rb +19 -10
- data/test/unit/tokenizer_unit_test.rb +19 -17
- data/test/unit/variable_unit_test.rb +51 -49
- metadata +83 -50
- data/lib/liquid/strainer.rb +0 -65
- data/test/unit/context_unit_test.rb +0 -483
- data/test/unit/strainer_unit_test.rb +0 -136
data/lib/liquid/condition.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
# Container for liquid nodes which conveniently wraps decision making logic
|
3
5
|
#
|
@@ -8,58 +10,83 @@ module Liquid
|
|
8
10
|
#
|
9
11
|
class Condition #:nodoc:
|
10
12
|
@@operators = {
|
11
|
-
'=='
|
12
|
-
'!='
|
13
|
-
'<>'
|
14
|
-
'<'
|
15
|
-
'>'
|
16
|
-
'>='
|
17
|
-
'<='
|
18
|
-
'contains'
|
13
|
+
'==' => ->(cond, left, right) { cond.send(:equal_variables, left, right) },
|
14
|
+
'!=' => ->(cond, left, right) { !cond.send(:equal_variables, left, right) },
|
15
|
+
'<>' => ->(cond, left, right) { !cond.send(:equal_variables, left, right) },
|
16
|
+
'<' => :<,
|
17
|
+
'>' => :>,
|
18
|
+
'>=' => :>=,
|
19
|
+
'<=' => :<=,
|
20
|
+
'contains' => lambda do |_cond, left, right|
|
19
21
|
if left && right && left.respond_to?(:include?)
|
20
22
|
right = right.to_s if left.is_a?(String)
|
21
23
|
left.include?(right)
|
22
24
|
else
|
23
25
|
false
|
24
26
|
end
|
27
|
+
end,
|
28
|
+
}
|
29
|
+
|
30
|
+
class MethodLiteral
|
31
|
+
attr_reader :method_name, :to_s
|
32
|
+
|
33
|
+
def initialize(method_name, to_s)
|
34
|
+
@method_name = method_name
|
35
|
+
@to_s = to_s
|
25
36
|
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@@method_literals = {
|
40
|
+
'blank' => MethodLiteral.new(:blank?, '').freeze,
|
41
|
+
'empty' => MethodLiteral.new(:empty?, '').freeze,
|
26
42
|
}
|
27
43
|
|
28
44
|
def self.operators
|
29
45
|
@@operators
|
30
46
|
end
|
31
47
|
|
32
|
-
|
48
|
+
def self.parse_expression(parse_context, markup)
|
49
|
+
@@method_literals[markup] || parse_context.parse_expression(markup)
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :attachment, :child_condition
|
33
53
|
attr_accessor :left, :operator, :right
|
34
54
|
|
35
55
|
def initialize(left = nil, operator = nil, right = nil)
|
36
|
-
@left
|
56
|
+
@left = left
|
37
57
|
@operator = operator
|
38
|
-
@right
|
58
|
+
@right = right
|
59
|
+
|
39
60
|
@child_relation = nil
|
40
61
|
@child_condition = nil
|
41
62
|
end
|
42
63
|
|
43
64
|
def evaluate(context = Context.new)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
65
|
+
condition = self
|
66
|
+
result = nil
|
67
|
+
loop do
|
68
|
+
result = interpret_condition(condition.left, condition.right, condition.operator, context)
|
69
|
+
|
70
|
+
case condition.child_relation
|
71
|
+
when :or
|
72
|
+
break if result
|
73
|
+
when :and
|
74
|
+
break unless result
|
75
|
+
else
|
76
|
+
break
|
77
|
+
end
|
78
|
+
condition = condition.child_condition
|
53
79
|
end
|
80
|
+
result
|
54
81
|
end
|
55
82
|
|
56
83
|
def or(condition)
|
57
|
-
@child_relation
|
84
|
+
@child_relation = :or
|
58
85
|
@child_condition = condition
|
59
86
|
end
|
60
87
|
|
61
88
|
def and(condition)
|
62
|
-
@child_relation
|
89
|
+
@child_relation = :and
|
63
90
|
@child_condition = condition
|
64
91
|
end
|
65
92
|
|
@@ -72,13 +99,17 @@ module Liquid
|
|
72
99
|
end
|
73
100
|
|
74
101
|
def inspect
|
75
|
-
"#<Condition #{[@left, @operator, @right].compact.join(' '
|
102
|
+
"#<Condition #{[@left, @operator, @right].compact.join(' ')}>"
|
76
103
|
end
|
77
104
|
|
105
|
+
protected
|
106
|
+
|
107
|
+
attr_reader :child_relation
|
108
|
+
|
78
109
|
private
|
79
110
|
|
80
111
|
def equal_variables(left, right)
|
81
|
-
if left.is_a?(
|
112
|
+
if left.is_a?(MethodLiteral)
|
82
113
|
if right.respond_to?(left.method_name)
|
83
114
|
return right.send(left.method_name)
|
84
115
|
else
|
@@ -86,7 +117,7 @@ module Liquid
|
|
86
117
|
end
|
87
118
|
end
|
88
119
|
|
89
|
-
if right.is_a?(
|
120
|
+
if right.is_a?(MethodLiteral)
|
90
121
|
if left.respond_to?(right.method_name)
|
91
122
|
return left.send(right.method_name)
|
92
123
|
else
|
@@ -103,21 +134,30 @@ module Liquid
|
|
103
134
|
# return this as the result.
|
104
135
|
return context.evaluate(left) if op.nil?
|
105
136
|
|
106
|
-
left
|
137
|
+
left = context.evaluate(left)
|
107
138
|
right = context.evaluate(right)
|
108
139
|
|
109
|
-
operation = self.class.operators[op] || raise(Liquid::ArgumentError
|
140
|
+
operation = self.class.operators[op] || raise(Liquid::ArgumentError, "Unknown operator #{op}")
|
110
141
|
|
111
142
|
if operation.respond_to?(:call)
|
112
143
|
operation.call(self, left, right)
|
113
|
-
elsif left.respond_to?(operation) && right.respond_to?(operation)
|
144
|
+
elsif left.respond_to?(operation) && right.respond_to?(operation) && !left.is_a?(Hash) && !right.is_a?(Hash)
|
114
145
|
begin
|
115
146
|
left.send(operation, right)
|
116
147
|
rescue ::ArgumentError => e
|
117
|
-
raise Liquid::ArgumentError
|
148
|
+
raise Liquid::ArgumentError, e.message
|
118
149
|
end
|
119
150
|
end
|
120
151
|
end
|
152
|
+
|
153
|
+
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
154
|
+
def children
|
155
|
+
[
|
156
|
+
@node.left, @node.right,
|
157
|
+
@node.child_condition, @node.attachment
|
158
|
+
].compact
|
159
|
+
end
|
160
|
+
end
|
121
161
|
end
|
122
162
|
|
123
163
|
class ElseCondition < Condition
|
data/lib/liquid/context.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
# Context keeps the variable stack and resolves variables, as well as keywords
|
3
5
|
#
|
@@ -12,36 +14,49 @@ module Liquid
|
|
12
14
|
#
|
13
15
|
# context['bob'] #=> nil class Context
|
14
16
|
class Context
|
15
|
-
attr_reader :scopes, :errors, :registers, :environments, :resource_limits
|
16
|
-
attr_accessor :
|
17
|
-
|
18
|
-
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
|
19
|
-
@environments = [environments].flatten
|
20
|
-
@scopes = [(outer_scope || {})]
|
21
|
-
@registers = registers
|
22
|
-
@errors = []
|
23
|
-
@partial = false
|
24
|
-
@strict_variables = false
|
25
|
-
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
26
|
-
squash_instance_assigns_with_environments
|
17
|
+
attr_reader :scopes, :errors, :registers, :environments, :resource_limits, :static_registers, :static_environments
|
18
|
+
attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
|
27
19
|
|
28
|
-
|
20
|
+
# rubocop:disable Metrics/ParameterLists
|
21
|
+
def self.build(environments: {}, outer_scope: {}, registers: {}, rethrow_errors: false, resource_limits: nil, static_environments: {}, &block)
|
22
|
+
new(environments, outer_scope, registers, rethrow_errors, resource_limits, static_environments, &block)
|
23
|
+
end
|
29
24
|
|
25
|
+
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil, static_environments = {})
|
26
|
+
@environments = [environments]
|
27
|
+
@environments.flatten!
|
28
|
+
|
29
|
+
@static_environments = [static_environments].flat_map(&:freeze).freeze
|
30
|
+
@scopes = [(outer_scope || {})]
|
31
|
+
@registers = registers
|
32
|
+
@errors = []
|
33
|
+
@partial = false
|
34
|
+
@strict_variables = false
|
35
|
+
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
36
|
+
@base_scope_depth = 0
|
37
|
+
@interrupts = []
|
38
|
+
@filters = []
|
39
|
+
@global_filter = nil
|
40
|
+
@disabled_tags = {}
|
41
|
+
|
42
|
+
self.exception_renderer = Template.default_exception_renderer
|
30
43
|
if rethrow_errors
|
31
|
-
self.
|
44
|
+
self.exception_renderer = Liquid::RAISE_EXCEPTION_LAMBDA
|
32
45
|
end
|
33
46
|
|
34
|
-
|
35
|
-
|
36
|
-
|
47
|
+
yield self if block_given?
|
48
|
+
|
49
|
+
# Do this last, since it could result in this object being passed to a Proc in the environment
|
50
|
+
squash_instance_assigns_with_environments
|
37
51
|
end
|
52
|
+
# rubocop:enable Metrics/ParameterLists
|
38
53
|
|
39
54
|
def warnings
|
40
55
|
@warnings ||= []
|
41
56
|
end
|
42
57
|
|
43
58
|
def strainer
|
44
|
-
@strainer ||=
|
59
|
+
@strainer ||= StrainerFactory.create(self, @filters)
|
45
60
|
end
|
46
61
|
|
47
62
|
# Adds filters to this context.
|
@@ -74,30 +89,11 @@ module Liquid
|
|
74
89
|
end
|
75
90
|
|
76
91
|
def handle_error(e, line_number = nil)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
output = nil
|
83
|
-
|
84
|
-
if exception_handler
|
85
|
-
result = exception_handler.call(e)
|
86
|
-
case result
|
87
|
-
when Exception
|
88
|
-
e = result
|
89
|
-
if e.is_a?(Liquid::Error)
|
90
|
-
e.template_name ||= template_name
|
91
|
-
e.line_number ||= line_number
|
92
|
-
end
|
93
|
-
when String
|
94
|
-
output = result
|
95
|
-
else
|
96
|
-
raise if result
|
97
|
-
end
|
98
|
-
end
|
92
|
+
e = internal_error unless e.is_a?(Liquid::Error)
|
93
|
+
e.template_name ||= template_name
|
94
|
+
e.line_number ||= line_number
|
99
95
|
errors.push(e)
|
100
|
-
|
96
|
+
exception_renderer.call(e).to_s
|
101
97
|
end
|
102
98
|
|
103
99
|
def invoke(method, *args)
|
@@ -107,7 +103,7 @@ module Liquid
|
|
107
103
|
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
|
108
104
|
def push(new_scope = {})
|
109
105
|
@scopes.unshift(new_scope)
|
110
|
-
|
106
|
+
check_overflow
|
111
107
|
end
|
112
108
|
|
113
109
|
# Merge a hash of variables in the current local scope
|
@@ -129,19 +125,31 @@ module Liquid
|
|
129
125
|
# end
|
130
126
|
#
|
131
127
|
# context['var] #=> nil
|
132
|
-
def stack(new_scope =
|
133
|
-
|
134
|
-
if new_scope
|
135
|
-
push(new_scope)
|
136
|
-
@this_stack_used = true
|
137
|
-
else
|
138
|
-
@this_stack_used = false
|
139
|
-
end
|
140
|
-
|
128
|
+
def stack(new_scope = {})
|
129
|
+
push(new_scope)
|
141
130
|
yield
|
142
131
|
ensure
|
143
|
-
pop
|
144
|
-
|
132
|
+
pop
|
133
|
+
end
|
134
|
+
|
135
|
+
# Creates a new context inheriting resource limits, filters, environment etc.,
|
136
|
+
# but with an isolated scope.
|
137
|
+
def new_isolated_subcontext
|
138
|
+
check_overflow
|
139
|
+
|
140
|
+
self.class.build(
|
141
|
+
resource_limits: resource_limits,
|
142
|
+
static_environments: static_environments,
|
143
|
+
registers: StaticRegisters.new(registers)
|
144
|
+
).tap do |subcontext|
|
145
|
+
subcontext.base_scope_depth = base_scope_depth + 1
|
146
|
+
subcontext.exception_renderer = exception_renderer
|
147
|
+
subcontext.filters = @filters
|
148
|
+
subcontext.strainer = nil
|
149
|
+
subcontext.errors = errors
|
150
|
+
subcontext.warnings = warnings
|
151
|
+
subcontext.disabled_tags = @disabled_tags
|
152
|
+
end
|
145
153
|
end
|
146
154
|
|
147
155
|
def clear_instance_assigns
|
@@ -150,10 +158,6 @@ module Liquid
|
|
150
158
|
|
151
159
|
# Only allow String, Numeric, Hash, Array, Proc, Boolean or <tt>Liquid::Drop</tt>
|
152
160
|
def []=(key, value)
|
153
|
-
unless @this_stack_used
|
154
|
-
@this_stack_used = true
|
155
|
-
push({})
|
156
|
-
end
|
157
161
|
@scopes[0][key] = value
|
158
162
|
end
|
159
163
|
|
@@ -178,49 +182,91 @@ module Liquid
|
|
178
182
|
end
|
179
183
|
|
180
184
|
# Fetches an object starting at the local scope and then moving up the hierachy
|
181
|
-
def find_variable(key)
|
185
|
+
def find_variable(key, raise_on_not_found: true)
|
182
186
|
# This was changed from find() to find_index() because this is a very hot
|
183
187
|
# path and find_index() is optimized in MRI to reduce object allocation
|
184
188
|
index = @scopes.find_index { |s| s.key?(key) }
|
185
|
-
scope = @scopes[index] if index
|
186
189
|
|
187
|
-
variable =
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
variable = lookup_and_evaluate(e, key)
|
192
|
-
unless variable.nil?
|
193
|
-
scope = e
|
194
|
-
break
|
195
|
-
end
|
196
|
-
end
|
190
|
+
variable = if index
|
191
|
+
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
|
192
|
+
else
|
193
|
+
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
|
197
194
|
end
|
198
195
|
|
199
|
-
|
200
|
-
variable ||= lookup_and_evaluate(scope, key)
|
201
|
-
|
202
|
-
variable = variable.to_liquid
|
196
|
+
variable = variable.to_liquid
|
203
197
|
variable.context = self if variable.respond_to?(:context=)
|
204
198
|
|
205
199
|
variable
|
206
200
|
end
|
207
201
|
|
208
|
-
def lookup_and_evaluate(obj, key)
|
209
|
-
if @strict_variables && obj.respond_to?(:key?) && !obj.key?(key)
|
202
|
+
def lookup_and_evaluate(obj, key, raise_on_not_found: true)
|
203
|
+
if @strict_variables && raise_on_not_found && obj.respond_to?(:key?) && !obj.key?(key)
|
210
204
|
raise Liquid::UndefinedVariable, "undefined variable #{key}"
|
211
205
|
end
|
212
206
|
|
213
207
|
value = obj[key]
|
214
208
|
|
215
209
|
if value.is_a?(Proc) && obj.respond_to?(:[]=)
|
216
|
-
obj[key] =
|
210
|
+
obj[key] = value.arity == 0 ? value.call : value.call(self)
|
217
211
|
else
|
218
212
|
value
|
219
213
|
end
|
220
214
|
end
|
221
215
|
|
216
|
+
def with_disabled_tags(tag_names)
|
217
|
+
tag_names.each do |name|
|
218
|
+
@disabled_tags[name] = @disabled_tags.fetch(name, 0) + 1
|
219
|
+
end
|
220
|
+
yield
|
221
|
+
ensure
|
222
|
+
tag_names.each do |name|
|
223
|
+
@disabled_tags[name] -= 1
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def tag_disabled?(tag_name)
|
228
|
+
@disabled_tags.fetch(tag_name, 0) > 0
|
229
|
+
end
|
230
|
+
|
231
|
+
protected
|
232
|
+
|
233
|
+
attr_writer :base_scope_depth, :warnings, :errors, :strainer, :filters, :disabled_tags
|
234
|
+
|
222
235
|
private
|
223
236
|
|
237
|
+
attr_reader :base_scope_depth
|
238
|
+
|
239
|
+
def try_variable_find_in_environments(key, raise_on_not_found:)
|
240
|
+
@environments.each do |environment|
|
241
|
+
found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)
|
242
|
+
if !found_variable.nil? || @strict_variables && raise_on_not_found
|
243
|
+
return found_variable
|
244
|
+
end
|
245
|
+
end
|
246
|
+
@static_environments.each do |environment|
|
247
|
+
found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)
|
248
|
+
if !found_variable.nil? || @strict_variables && raise_on_not_found
|
249
|
+
return found_variable
|
250
|
+
end
|
251
|
+
end
|
252
|
+
nil
|
253
|
+
end
|
254
|
+
|
255
|
+
def check_overflow
|
256
|
+
raise StackLevelError, "Nesting too deep" if overflow?
|
257
|
+
end
|
258
|
+
|
259
|
+
def overflow?
|
260
|
+
base_scope_depth + @scopes.length > Block::MAX_DEPTH
|
261
|
+
end
|
262
|
+
|
263
|
+
def internal_error
|
264
|
+
# raise and catch to set backtrace and cause on exception
|
265
|
+
raise Liquid::InternalError, 'internal'
|
266
|
+
rescue Liquid::InternalError => exc
|
267
|
+
exc
|
268
|
+
end
|
269
|
+
|
224
270
|
def squash_instance_assigns_with_environments
|
225
271
|
@scopes.last.each_key do |k|
|
226
272
|
@environments.each do |env|
|