twig_ruby 0.0.1 → 0.0.2
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 +4 -4
- data/lib/tasks/twig_parity.rake +278 -0
- data/lib/twig/auto_hash.rb +7 -1
- data/lib/twig/callable.rb +28 -1
- data/lib/twig/compiler.rb +35 -3
- data/lib/twig/environment.rb +198 -41
- data/lib/twig/error/base.rb +81 -16
- data/lib/twig/error/loader.rb +8 -0
- data/lib/twig/error/logic.rb +8 -0
- data/lib/twig/error/runtime.rb +8 -0
- data/lib/twig/expression_parser/base.rb +30 -0
- data/lib/twig/expression_parser/expression_parsers.rb +57 -0
- data/lib/twig/expression_parser/infix/arrow.rb +31 -0
- data/lib/twig/expression_parser/infix/binary.rb +34 -0
- data/lib/twig/expression_parser/infix/conditional_ternary.rb +39 -0
- data/lib/twig/expression_parser/infix/dot.rb +72 -0
- data/lib/twig/expression_parser/infix/filter.rb +43 -0
- data/lib/twig/expression_parser/infix/function.rb +67 -0
- data/lib/twig/expression_parser/infix/is.rb +53 -0
- data/lib/twig/expression_parser/infix/is_not.rb +19 -0
- data/lib/twig/expression_parser/infix/parses_arguments.rb +84 -0
- data/lib/twig/expression_parser/infix/square_bracket.rb +66 -0
- data/lib/twig/expression_parser/infix_expression_parser.rb +34 -0
- data/lib/twig/expression_parser/prefix/grouping.rb +60 -0
- data/lib/twig/expression_parser/prefix/literal.rb +244 -0
- data/lib/twig/expression_parser/prefix/unary.rb +29 -0
- data/lib/twig/expression_parser/prefix_expression_parser.rb +18 -0
- data/lib/twig/extension/base.rb +26 -4
- data/lib/twig/extension/core.rb +1076 -48
- data/lib/twig/extension/debug.rb +25 -0
- data/lib/twig/extension/escaper.rb +73 -0
- data/lib/twig/extension/rails.rb +10 -57
- data/lib/twig/extension/string_loader.rb +19 -0
- data/lib/twig/extension_set.rb +117 -20
- data/lib/twig/file_extension_escaping_strategy.rb +35 -0
- data/lib/twig/lexer.rb +225 -81
- data/lib/twig/loader/array.rb +25 -8
- data/lib/twig/loader/chain.rb +93 -0
- data/lib/twig/loader/filesystem.rb +106 -7
- data/lib/twig/node/auto_escape.rb +18 -0
- data/lib/twig/node/base.rb +58 -2
- data/lib/twig/node/block.rb +2 -0
- data/lib/twig/node/block_reference.rb +5 -1
- data/lib/twig/node/body.rb +7 -0
- data/lib/twig/node/cache.rb +50 -0
- data/lib/twig/node/capture.rb +22 -0
- data/lib/twig/node/deprecated.rb +53 -0
- data/lib/twig/node/do.rb +19 -0
- data/lib/twig/node/embed.rb +43 -0
- data/lib/twig/node/expression/array.rb +29 -20
- data/lib/twig/node/expression/arrow_function.rb +55 -0
- data/lib/twig/node/expression/assign_name.rb +1 -1
- data/lib/twig/node/expression/binary/and.rb +17 -0
- data/lib/twig/node/expression/binary/base.rb +6 -4
- data/lib/twig/node/expression/binary/boolean.rb +24 -0
- data/lib/twig/node/expression/binary/concat.rb +20 -0
- data/lib/twig/node/expression/binary/elvis.rb +35 -0
- data/lib/twig/node/expression/binary/ends_with.rb +24 -0
- data/lib/twig/node/expression/binary/floor_div.rb +21 -0
- data/lib/twig/node/expression/binary/has_every.rb +20 -0
- data/lib/twig/node/expression/binary/has_some.rb +20 -0
- data/lib/twig/node/expression/binary/in.rb +20 -0
- data/lib/twig/node/expression/binary/matches.rb +24 -0
- data/lib/twig/node/expression/binary/not_in.rb +20 -0
- data/lib/twig/node/expression/binary/null_coalesce.rb +49 -0
- data/lib/twig/node/expression/binary/or.rb +15 -0
- data/lib/twig/node/expression/binary/starts_with.rb +24 -0
- data/lib/twig/node/expression/binary/xor.rb +17 -0
- data/lib/twig/node/expression/block_reference.rb +62 -0
- data/lib/twig/node/expression/call.rb +126 -6
- data/lib/twig/node/expression/constant.rb +3 -1
- data/lib/twig/node/expression/filter/default.rb +37 -0
- data/lib/twig/node/expression/filter/raw.rb +31 -0
- data/lib/twig/node/expression/filter.rb +2 -2
- data/lib/twig/node/expression/function.rb +37 -0
- data/lib/twig/node/expression/get_attribute.rb +51 -7
- data/lib/twig/node/expression/hash.rb +75 -0
- data/lib/twig/node/expression/helper_method.rb +6 -18
- data/lib/twig/node/expression/macro_reference.rb +43 -0
- data/lib/twig/node/expression/name.rb +42 -8
- data/lib/twig/node/expression/operator_escape.rb +13 -0
- data/lib/twig/node/expression/parent.rb +28 -0
- data/lib/twig/node/expression/support_defined_test.rb +23 -0
- data/lib/twig/node/expression/ternary.rb +7 -1
- data/lib/twig/node/expression/test/base.rb +26 -0
- data/lib/twig/node/expression/test/constant.rb +35 -0
- data/lib/twig/node/expression/test/defined.rb +33 -0
- data/lib/twig/node/expression/test/divisible_by.rb +23 -0
- data/lib/twig/node/expression/test/even.rb +21 -0
- data/lib/twig/node/expression/test/iterable.rb +21 -0
- data/lib/twig/node/expression/test/mapping.rb +21 -0
- data/lib/twig/node/expression/test/null.rb +21 -0
- data/lib/twig/node/expression/test/odd.rb +21 -0
- data/lib/twig/node/expression/test/same_as.rb +23 -0
- data/lib/twig/node/expression/test/sequence.rb +21 -0
- data/lib/twig/node/expression/unary/base.rb +3 -1
- data/lib/twig/node/expression/unary/not.rb +18 -0
- data/lib/twig/node/expression/unary/spread.rb +18 -0
- data/lib/twig/node/expression/unary/string_cast.rb +18 -0
- data/lib/twig/node/expression/variable/assign_template.rb +35 -0
- data/lib/twig/node/expression/variable/local.rb +35 -0
- data/lib/twig/node/expression/variable/template.rb +54 -0
- data/lib/twig/node/for.rb +38 -8
- data/lib/twig/node/for_loop.rb +0 -22
- data/lib/twig/node/if.rb +4 -1
- data/lib/twig/node/import.rb +32 -0
- data/lib/twig/node/include.rb +38 -8
- data/lib/twig/node/macro.rb +79 -0
- data/lib/twig/node/module.rb +278 -23
- data/lib/twig/node/output.rb +7 -0
- data/lib/twig/node/print.rb +4 -1
- data/lib/twig/node/set.rb +72 -0
- data/lib/twig/node/text.rb +4 -1
- data/lib/twig/node/with.rb +50 -0
- data/lib/twig/node/yield.rb +6 -1
- data/lib/twig/node_traverser.rb +50 -0
- data/lib/twig/node_visitor/base.rb +30 -0
- data/lib/twig/node_visitor/escaper.rb +165 -0
- data/lib/twig/node_visitor/safe_analysis.rb +127 -0
- data/lib/twig/node_visitor/spreader.rb +39 -0
- data/lib/twig/output_buffer.rb +14 -12
- data/lib/twig/parser.rb +281 -8
- data/lib/twig/rails/config.rb +33 -0
- data/lib/twig/rails/engine.rb +44 -0
- data/lib/twig/rails/renderer.rb +41 -0
- data/lib/twig/runtime/argument_spreader.rb +46 -0
- data/lib/twig/runtime/context.rb +154 -0
- data/lib/twig/runtime/enumerable_hash.rb +51 -0
- data/lib/twig/runtime/escaper.rb +155 -0
- data/lib/twig/runtime/loop_context.rb +81 -0
- data/lib/twig/runtime/loop_iterator.rb +60 -0
- data/lib/twig/runtime/spread.rb +21 -0
- data/lib/twig/runtime_loader/base.rb +12 -0
- data/lib/twig/runtime_loader/factory.rb +23 -0
- data/lib/twig/template.rb +267 -14
- data/lib/twig/template_wrapper.rb +42 -0
- data/lib/twig/token.rb +28 -2
- data/lib/twig/token_parser/apply.rb +48 -0
- data/lib/twig/token_parser/auto_escape.rb +45 -0
- data/lib/twig/token_parser/base.rb +26 -0
- data/lib/twig/token_parser/block.rb +4 -4
- data/lib/twig/token_parser/cache.rb +31 -0
- data/lib/twig/token_parser/deprecated.rb +40 -0
- data/lib/twig/token_parser/do.rb +19 -0
- data/lib/twig/token_parser/embed.rb +62 -0
- data/lib/twig/token_parser/extends.rb +4 -3
- data/lib/twig/token_parser/for.rb +14 -9
- data/lib/twig/token_parser/from.rb +57 -0
- data/lib/twig/token_parser/guard.rb +65 -0
- data/lib/twig/token_parser/if.rb +9 -9
- data/lib/twig/token_parser/import.rb +29 -0
- data/lib/twig/token_parser/include.rb +2 -2
- data/lib/twig/token_parser/macro.rb +109 -0
- data/lib/twig/token_parser/set.rb +76 -0
- data/lib/twig/token_parser/use.rb +54 -0
- data/lib/twig/token_parser/with.rb +36 -0
- data/lib/twig/token_parser/yield.rb +7 -7
- data/lib/twig/token_stream.rb +23 -3
- data/lib/twig/twig_filter.rb +20 -0
- data/lib/twig/twig_function.rb +37 -0
- data/lib/twig/twig_test.rb +31 -0
- data/lib/twig/util/callable_arguments_extractor.rb +227 -0
- data/lib/twig_ruby.rb +21 -2
- metadata +145 -6
- data/lib/twig/context.rb +0 -64
- data/lib/twig/expression_parser.rb +0 -517
- data/lib/twig/railtie.rb +0 -60
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Twig
|
|
4
|
+
module ExpressionParser
|
|
5
|
+
module Prefix
|
|
6
|
+
class Literal < PrefixExpressionParser
|
|
7
|
+
def parse(parser, token)
|
|
8
|
+
case token.type
|
|
9
|
+
when Token::SYMBOL_TYPE
|
|
10
|
+
parser.stream.next
|
|
11
|
+
@type = :constant
|
|
12
|
+
|
|
13
|
+
return Node::Expression::Constant.new(token.value.to_sym, token.lineno)
|
|
14
|
+
when Token::CLASS_VAR_TYPE
|
|
15
|
+
parser.stream.next
|
|
16
|
+
@type = :variable
|
|
17
|
+
|
|
18
|
+
return Node::Expression::Variable::Context.new(token.value, token.lineno)
|
|
19
|
+
when Token::NAME_TYPE
|
|
20
|
+
parser.stream.next
|
|
21
|
+
|
|
22
|
+
# We can adjust for a ternary with no space here like a? b : c, we should however ignore function
|
|
23
|
+
# nodes because a?() is fine
|
|
24
|
+
token_value = token.value
|
|
25
|
+
if token.value.end_with?('?') && parser.current_token.value != '('
|
|
26
|
+
parser.stream.inject([Token.new(Token::OPERATOR_TYPE, '?', token.lineno)])
|
|
27
|
+
token_value = token.value.chomp('?')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
case token_value
|
|
31
|
+
when 'true', 'TRUE'
|
|
32
|
+
@type = :constant
|
|
33
|
+
|
|
34
|
+
return Node::Expression::Constant.new(true, token.lineno)
|
|
35
|
+
when 'false', 'FALSE'
|
|
36
|
+
@type = :constant
|
|
37
|
+
|
|
38
|
+
return Node::Expression::Constant.new(false, token.lineno)
|
|
39
|
+
when 'null', 'NULL', 'nil', 'none', 'NONE'
|
|
40
|
+
@type = :constant
|
|
41
|
+
|
|
42
|
+
return Node::Expression::Constant.new(nil, token.lineno)
|
|
43
|
+
else
|
|
44
|
+
@type = :variable
|
|
45
|
+
|
|
46
|
+
return Node::Expression::Variable::Context.new(token_value, token.lineno)
|
|
47
|
+
end
|
|
48
|
+
when Token::NUMBER_TYPE
|
|
49
|
+
parser.stream.next
|
|
50
|
+
@type = :constant
|
|
51
|
+
|
|
52
|
+
return Node::Expression::Constant.new(token.value, token.lineno)
|
|
53
|
+
when Token::STRING_TYPE, Token::INTERPOLATION_START_TYPE
|
|
54
|
+
@type = :string
|
|
55
|
+
|
|
56
|
+
return parse_string_expression(parser)
|
|
57
|
+
when Token::PUNCTUATION_TYPE
|
|
58
|
+
if token.value == '{'
|
|
59
|
+
return parse_mapping_expression(parser)
|
|
60
|
+
else
|
|
61
|
+
raise Error::Syntax.new(
|
|
62
|
+
"Unexpected token \"#{token.to_english}\" of value \"#{token.value}\".",
|
|
63
|
+
token.lineno,
|
|
64
|
+
parser.stream.source
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
when Token::OPERATOR_TYPE
|
|
68
|
+
if token.value == '['
|
|
69
|
+
return parse_sequence_expression(parser)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if (match = token.value.match(Lexer::REGEX_NAME)) && match.to_s == token.value
|
|
73
|
+
# in this context, string operators are variable names
|
|
74
|
+
parser.stream.next
|
|
75
|
+
@type = :variable
|
|
76
|
+
|
|
77
|
+
return Node::Expression::Variable::Context.new(token.value, token.lineno)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if token.value == '=' && %w[== !=].include?(parser.stream.look(-1).value)
|
|
81
|
+
raise Error::Syntax.new(
|
|
82
|
+
"Unexpected operator of value \"#{token.value}\". Did you try to use \"===\" or \"!==\" for " \
|
|
83
|
+
'strict comparison? Use "is same as(value)" instead.',
|
|
84
|
+
token.lineno,
|
|
85
|
+
parser.stream.source
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
raise Error::Syntax.new(
|
|
91
|
+
"Unexpected token \"#{token.type}\" of value \"#{token.value}\".",
|
|
92
|
+
token.lineno,
|
|
93
|
+
parser.stream.source
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def name
|
|
98
|
+
@type || :literal
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def precedence
|
|
102
|
+
0
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
# @param [Parser]
|
|
108
|
+
def parse_string_expression(parser)
|
|
109
|
+
stream = parser.stream
|
|
110
|
+
nodes = []
|
|
111
|
+
|
|
112
|
+
# a string cannot be followed by another string in a single expression
|
|
113
|
+
next_can_be_string = true
|
|
114
|
+
|
|
115
|
+
loop do
|
|
116
|
+
if next_can_be_string && (token = stream.next_if(Token::STRING_TYPE))
|
|
117
|
+
nodes << Node::Expression::Constant.new(token.value, token.lineno)
|
|
118
|
+
next_can_be_string = false
|
|
119
|
+
elsif stream.next_if(Token::INTERPOLATION_START_TYPE)
|
|
120
|
+
nodes << parser.parse_expression
|
|
121
|
+
stream.expect(Token::INTERPOLATION_END_TYPE)
|
|
122
|
+
next_can_be_string = true
|
|
123
|
+
else
|
|
124
|
+
break
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
expr = nodes.shift
|
|
129
|
+
nodes.each do |node|
|
|
130
|
+
expr = Node::Expression::Binary::Concat.new(expr, node, node.lineno)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
expr
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @param [Parser] parser
|
|
137
|
+
def parse_sequence_expression(parser)
|
|
138
|
+
@type = :sequence
|
|
139
|
+
|
|
140
|
+
stream = parser.stream
|
|
141
|
+
stream.expect(Token::OPERATOR_TYPE, '[', 'A sequence element was expected')
|
|
142
|
+
|
|
143
|
+
node = Node::Expression::Array.new(AutoHash.new, stream.current.lineno)
|
|
144
|
+
first = true
|
|
145
|
+
|
|
146
|
+
# raise stream.debug
|
|
147
|
+
|
|
148
|
+
until stream.test(Token::PUNCTUATION_TYPE, ']')
|
|
149
|
+
unless first
|
|
150
|
+
stream.expect(Token::PUNCTUATION_TYPE, ',', 'A sequence element must be followed by a comma')
|
|
151
|
+
|
|
152
|
+
# trailing comma
|
|
153
|
+
break if stream.test(Token::PUNCTUATION_TYPE, ']')
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
first = false
|
|
157
|
+
|
|
158
|
+
if stream.next_if(Token::OPERATOR_TYPE, '...')
|
|
159
|
+
expr = parser.parse_expression
|
|
160
|
+
node.add_element(Node::Expression::Unary::ArraySpread.new(expr, expr.lineno))
|
|
161
|
+
else
|
|
162
|
+
node.add_element(parser.parse_expression)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
stream.expect(Token::PUNCTUATION_TYPE, ']', 'An opened sequence is not properly closed')
|
|
167
|
+
|
|
168
|
+
node
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# @param [Parser] parser
|
|
172
|
+
def parse_mapping_expression(parser)
|
|
173
|
+
@type = :mapping
|
|
174
|
+
|
|
175
|
+
stream = parser.stream
|
|
176
|
+
stream.expect(Token::PUNCTUATION_TYPE, '{', 'A mapping element was expected')
|
|
177
|
+
|
|
178
|
+
node = Node::Expression::Hash.new({}, stream.current.lineno)
|
|
179
|
+
first = true
|
|
180
|
+
|
|
181
|
+
until stream.test(Token::PUNCTUATION_TYPE, '}')
|
|
182
|
+
unless first
|
|
183
|
+
stream.expect(Token::PUNCTUATION_TYPE, ',', 'A mapping value must be followed by a comma')
|
|
184
|
+
|
|
185
|
+
# trailing comma
|
|
186
|
+
if stream.test(Token::PUNCTUATION_TYPE, '}')
|
|
187
|
+
break
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
first = false
|
|
192
|
+
|
|
193
|
+
if stream.next_if(Token::OPERATOR_TYPE, '...')
|
|
194
|
+
value = parser.parse_expression
|
|
195
|
+
node.add_element(Node::Expression::Unary::HashSpread.new(value, value.lineno))
|
|
196
|
+
|
|
197
|
+
next
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# a mapping key can be:
|
|
201
|
+
#
|
|
202
|
+
# * a number -- 12
|
|
203
|
+
# * a string -- 'a'
|
|
204
|
+
# * a name, which is equivalent to a symbol -- a
|
|
205
|
+
# * an expression, which must be enclosed in parentheses -- (1 + 2)
|
|
206
|
+
if (token = stream.next_if(Token::NAME_TYPE))
|
|
207
|
+
key = Node::Expression::Constant.new(token.value.to_sym, token.lineno)
|
|
208
|
+
|
|
209
|
+
# {a} is a shortcut for {a: a}
|
|
210
|
+
if stream.test(Token::PUNCTUATION_TYPE, %w[, }])
|
|
211
|
+
value = Node::Expression::Variable::Context.new(key.attributes[:value], key.lineno)
|
|
212
|
+
node.add_element(value, key)
|
|
213
|
+
|
|
214
|
+
next
|
|
215
|
+
end
|
|
216
|
+
elsif (token = stream.next_if(Token::STRING_TYPE)) || (token = stream.next_if(Token::NUMBER_TYPE))
|
|
217
|
+
key = Node::Expression::Constant.new(token.value, token.lineno)
|
|
218
|
+
elsif stream.test(Token::OPERATOR_TYPE, '(')
|
|
219
|
+
key = parser.parse_expression
|
|
220
|
+
else
|
|
221
|
+
current = stream.current
|
|
222
|
+
|
|
223
|
+
raise Error::Syntax.new(
|
|
224
|
+
'A mapping key must be a quoted string, number, name, or expression in parentheses ' \
|
|
225
|
+
"expected token '#{current.type}' of value '#{current.value}'.",
|
|
226
|
+
current.lineno,
|
|
227
|
+
stream.source
|
|
228
|
+
)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
stream.expect(Token::PUNCTUATION_TYPE, ':', 'A mapping key must be followed by a colon (:)')
|
|
232
|
+
value = parser.parse_expression
|
|
233
|
+
|
|
234
|
+
node.add_element(value, key)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
stream.expect(Token::PUNCTUATION_TYPE, '}', 'An opened mapping is not properly closed')
|
|
238
|
+
|
|
239
|
+
node
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Twig
|
|
4
|
+
module ExpressionParser
|
|
5
|
+
module Prefix
|
|
6
|
+
class Unary < PrefixExpressionParser
|
|
7
|
+
attr_reader :aliases, :precedence, :name
|
|
8
|
+
|
|
9
|
+
def initialize(node_class, name, precedence, description: nil, aliases: [])
|
|
10
|
+
super()
|
|
11
|
+
|
|
12
|
+
@node_class = node_class
|
|
13
|
+
@name = name
|
|
14
|
+
@precedence = precedence
|
|
15
|
+
@description = description
|
|
16
|
+
@aliases = aliases
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parse(parser, token)
|
|
20
|
+
@node_class.new(parser.parse_expression(precedence), token.lineno)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def description
|
|
24
|
+
@description || ''
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Twig
|
|
4
|
+
module ExpressionParser
|
|
5
|
+
class PrefixExpressionParser < ExpressionParser::Base
|
|
6
|
+
# @param [Parser] parser
|
|
7
|
+
# @param [Token] token
|
|
8
|
+
# @return [Node::Expression::Base]
|
|
9
|
+
def parse(parser, token)
|
|
10
|
+
raise NotImplementedError
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def type
|
|
14
|
+
:prefix
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/twig/extension/base.rb
CHANGED
|
@@ -3,21 +3,43 @@
|
|
|
3
3
|
module Twig
|
|
4
4
|
module Extension
|
|
5
5
|
class Base
|
|
6
|
-
def
|
|
7
|
-
[
|
|
6
|
+
def expression_parsers
|
|
7
|
+
[]
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def filters
|
|
11
|
-
|
|
11
|
+
[]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def functions
|
|
15
|
+
[]
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
def token_parsers
|
|
15
19
|
[]
|
|
16
20
|
end
|
|
17
21
|
|
|
18
|
-
def
|
|
22
|
+
def tests
|
|
23
|
+
[]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def node_visitors
|
|
19
27
|
[]
|
|
20
28
|
end
|
|
29
|
+
|
|
30
|
+
def globals
|
|
31
|
+
{}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def static(method)
|
|
37
|
+
self.class.method(method)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def runtime(klass, method)
|
|
41
|
+
[:runtime, klass, method]
|
|
42
|
+
end
|
|
21
43
|
end
|
|
22
44
|
end
|
|
23
45
|
end
|