jsrb 0.2.1 → 0.3.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 +4 -4
- data/.rubocop.yml +6 -5
- data/.yardopts +3 -0
- data/README.md +108 -95
- data/jsrb.gemspec +0 -2
- data/lib/jsrb/base.rb +157 -26
- data/lib/jsrb/cond_chain.rb +17 -12
- data/lib/jsrb/expr_chain.rb +90 -295
- data/lib/jsrb/js_statement_context.rb +8 -8
- data/lib/jsrb/railtie.rb +1 -1
- data/lib/jsrb/version.rb +1 -1
- metadata +2 -2
data/lib/jsrb/cond_chain.rb
CHANGED
@@ -20,7 +20,6 @@ module Jsrb
|
|
20
20
|
def end
|
21
21
|
finalize(nil)
|
22
22
|
end
|
23
|
-
alias end! end
|
24
23
|
|
25
24
|
private
|
26
25
|
|
@@ -39,7 +38,7 @@ module Jsrb
|
|
39
38
|
else
|
40
39
|
@context.push(
|
41
40
|
type: 'ExpressionStatement',
|
42
|
-
expression: if_value.
|
41
|
+
expression: if_value.object
|
43
42
|
)
|
44
43
|
end
|
45
44
|
end
|
@@ -47,20 +46,26 @@ module Jsrb
|
|
47
46
|
def create_proc(block)
|
48
47
|
lambda do
|
49
48
|
final_alternate_stmt = block && @context.new_block do
|
50
|
-
@context.
|
51
|
-
type: '
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
@context.push(
|
50
|
+
type: 'ReturnStatement',
|
51
|
+
argument: {
|
52
|
+
type: 'CallExpression',
|
53
|
+
callee: @context.ruby_to_js_ast(block),
|
54
|
+
arguments: []
|
55
|
+
}
|
56
|
+
)
|
55
57
|
end
|
56
58
|
if_stmt = @stack.reverse.reduce(final_alternate_stmt) do |alternate_stmt, cond_block|
|
57
59
|
condition_expr, cond_block = cond_block
|
58
60
|
consequent_stmt = @context.new_block do
|
59
|
-
@context.
|
60
|
-
type: '
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
@context.push(
|
62
|
+
type: 'ReturnStatement',
|
63
|
+
argument: {
|
64
|
+
type: 'CallExpression',
|
65
|
+
callee: @context.ruby_to_js_ast(cond_block),
|
66
|
+
arguments: []
|
67
|
+
}
|
68
|
+
)
|
64
69
|
end
|
65
70
|
stmt_ast = {
|
66
71
|
type: 'IfStatement',
|
data/lib/jsrb/expr_chain.rb
CHANGED
@@ -2,209 +2,86 @@
|
|
2
2
|
|
3
3
|
module Jsrb
|
4
4
|
# ExprChain is a builder class that constructs JavaScript expressions
|
5
|
-
# in natural phrase by
|
5
|
+
# in natural phrase by chaining methods.
|
6
|
+
#
|
7
|
+
# Note that ExprChain does NOT add any statement to be rendered.
|
8
|
+
# If you want to add the expression as an **ExpressionStatement**,
|
9
|
+
# use `Jsrb::Base#do!`:
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# js.do!(obj.foo = 100) # pushes a statement `obj.foo = 100;`.
|
13
|
+
# # where `obj.foo = 100` is still a chainable ExprChain instance,
|
14
|
+
# # so that we have to explicitly push it as statement with `js.do!`.
|
15
|
+
# ```
|
6
16
|
class ExprChain
|
7
17
|
JS_LOGICAL_OPS = %w[&& ||].freeze
|
8
18
|
|
19
|
+
#
|
20
|
+
# Gets a current wrapped AST node.
|
21
|
+
# @private
|
22
|
+
# @return [Hash, nil] current abstract syntax tree
|
23
|
+
attr_reader :object
|
24
|
+
|
9
25
|
# Returns a new instance.
|
26
|
+
# @private
|
10
27
|
# @param [Jsrb::JSStatementContext] context statement context instance
|
11
|
-
# @param
|
28
|
+
# @param [Hash, nil] object hash represents AST node
|
12
29
|
def initialize(context, object = nil)
|
13
30
|
@context = context
|
14
31
|
@object = object
|
15
32
|
end
|
16
33
|
|
17
|
-
# Responds arbitrary method name
|
18
34
|
#
|
19
|
-
#
|
20
|
-
# constructs a **MemberExpression**
|
35
|
+
# Responds to arbitrary method names
|
21
36
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# obj.foo # represents `obj.foo`
|
25
|
-
# ```
|
37
|
+
# @example
|
38
|
+
# obj = js.expr[:obj]
|
26
39
|
#
|
27
|
-
#
|
28
|
-
#
|
40
|
+
# # If the last character of the method name is neither `=` nor `?`,
|
41
|
+
# # and no argument and no block given,
|
42
|
+
# # it constructs a **MemberExpression**.
|
29
43
|
#
|
30
|
-
#
|
31
|
-
# obj = jsrb.expr['obj']
|
32
|
-
# obj.foo(100) # represents `obj.foo(100)`
|
33
|
-
# obj.foo { |x| x + 1 } # represents `obj.foo(function (x) { return x; })`
|
34
|
-
# ```
|
44
|
+
# obj.foo # => ExprChain `obj.foo`
|
35
45
|
#
|
36
|
-
#
|
37
|
-
#
|
46
|
+
# # If the last character of the method name is neither `=` nor `?`,
|
47
|
+
# # at least one argument or block given,
|
48
|
+
# # it constructs a **CallExpression** of MemberExpression.
|
38
49
|
#
|
39
|
-
#
|
40
|
-
# obj
|
41
|
-
# obj.foo = 100 # pushes `obj.foo = 100;` in the current context
|
42
|
-
# ```
|
50
|
+
# obj.foo(100) # => ExprChain `obj.foo(100)`
|
51
|
+
# obj.foo { |x| x + 1 } # ExprChain `obj.foo(function (x) { return x; })`
|
43
52
|
#
|
44
|
-
#
|
45
|
-
# constructs **
|
53
|
+
# # If the last character of the method name is `=`,
|
54
|
+
# # it constructs **AssignmentExpression** of a member assignment expression.
|
46
55
|
#
|
47
|
-
#
|
48
|
-
# obj = jsrb.expr['obj']
|
49
|
-
# obj.foo?(100, 200) # represents `obj.foo ? 100 : 200`
|
50
|
-
# ```
|
56
|
+
# (obj.foo = 100) # ExprChain `obj.foo = 100`
|
51
57
|
#
|
58
|
+
# # If the last character of the method name is `?`,
|
59
|
+
# # it constructs **ConditionalExpression**.
|
60
|
+
#
|
61
|
+
# obj.foo?(100, 200) # => ExprChain `obj.foo ? 100 : 200`
|
52
62
|
def method_missing(name, *args, &block)
|
53
63
|
if (matches = name.to_s.match(/\A(.+)\?\z/))
|
54
|
-
|
64
|
+
self[matches[1]].cond?(*args)
|
55
65
|
elsif (matches = name.to_s.match(/\A(.+)=\z/))
|
56
|
-
|
66
|
+
self[matches[1]].set(*args)
|
57
67
|
elsif (function_name = self.class.custom_chains[name.to_sym])
|
58
|
-
|
68
|
+
_bind_chain!(function_name, *args, &block)
|
59
69
|
elsif args.empty? && !block
|
60
|
-
|
70
|
+
self[name.to_s]
|
61
71
|
else
|
62
|
-
|
72
|
+
self[name.to_s].call(*args, &block)
|
63
73
|
end
|
64
74
|
end
|
65
75
|
|
66
76
|
#
|
67
77
|
# Constructs a **MemberExpression**
|
68
78
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# x.set! obj['field']
|
73
|
-
# ```
|
74
|
-
#
|
75
|
-
# will be
|
76
|
-
#
|
77
|
-
# ```js
|
78
|
-
# x = someObj['field'];
|
79
|
-
# ```
|
80
|
-
#
|
79
|
+
# @example
|
80
|
+
# obj = js.expr[:someObj]
|
81
|
+
# obj[:field] # => ExprChain `someObj['field']`
|
81
82
|
# @param [String, Symbol] value name of member
|
82
83
|
# @return [Jsrb::ExprChain] a chain represents **MemberExpression**
|
83
84
|
def [](value)
|
84
|
-
member!(value)
|
85
|
-
end
|
86
|
-
|
87
|
-
#
|
88
|
-
# Gets current wrapped AST node.
|
89
|
-
#
|
90
|
-
# @return [Hash, nil] current abstract syntax tree
|
91
|
-
def unwrap!
|
92
|
-
@object
|
93
|
-
end
|
94
|
-
|
95
|
-
#
|
96
|
-
# pushes the current expression as a **ExpressionStatement** into the context.
|
97
|
-
#
|
98
|
-
# ```rb
|
99
|
-
# jsrb.expr['console'].log('hello').as_statement!
|
100
|
-
# ```
|
101
|
-
#
|
102
|
-
# will be
|
103
|
-
#
|
104
|
-
# ```js
|
105
|
-
# console.log('hello');
|
106
|
-
# ```
|
107
|
-
#
|
108
|
-
# @return [nil]
|
109
|
-
def as_statement!
|
110
|
-
raise ArgumentError, "Can't chain as_statement! on empty context" unless @object
|
111
|
-
|
112
|
-
@context.push(
|
113
|
-
type: 'ExpressionStatement',
|
114
|
-
expression: @object
|
115
|
-
)
|
116
|
-
nil # chain ends
|
117
|
-
end
|
118
|
-
|
119
|
-
#
|
120
|
-
# pushes a **VariableDeclaration** whose initializer is the current expression into the context.
|
121
|
-
#
|
122
|
-
# ```rb
|
123
|
-
# name = jsrb.var!(:name) { 'foo' }
|
124
|
-
# ary = jsrb.var! :ary
|
125
|
-
# obj = jsrb.var! :obj
|
126
|
-
# result = jsrb.var!
|
127
|
-
# ```
|
128
|
-
#
|
129
|
-
# will be
|
130
|
-
#
|
131
|
-
# ```js
|
132
|
-
# var name = 'foo';
|
133
|
-
# var ary;
|
134
|
-
# var obj;
|
135
|
-
# var _v1; //<- auto generate variable name
|
136
|
-
# ```
|
137
|
-
#
|
138
|
-
# @param [String, Symbol] id variable name
|
139
|
-
# @return [nil]
|
140
|
-
def as_variable_declaration!(id)
|
141
|
-
if @object
|
142
|
-
@context.push(
|
143
|
-
type: 'VariableDeclaration',
|
144
|
-
declarations: [{
|
145
|
-
type: 'VariableDeclarator',
|
146
|
-
id: {
|
147
|
-
type: 'Identifier',
|
148
|
-
name: id.to_s
|
149
|
-
},
|
150
|
-
init: @object
|
151
|
-
}],
|
152
|
-
kind: 'var'
|
153
|
-
)
|
154
|
-
else
|
155
|
-
@context.push(
|
156
|
-
type: 'VariableDeclaration',
|
157
|
-
declarations: [{
|
158
|
-
type: 'VariableDeclarator',
|
159
|
-
id: {
|
160
|
-
type: 'Identifier',
|
161
|
-
name: id.to_s
|
162
|
-
}
|
163
|
-
}],
|
164
|
-
kind: 'var'
|
165
|
-
)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
#
|
170
|
-
# pushes a **ReturnStatement** whose argument is the current expression into the context.
|
171
|
-
#
|
172
|
-
# ```rb
|
173
|
-
# jsrb.expr['getItems'].().as_return!
|
174
|
-
# ```
|
175
|
-
#
|
176
|
-
# will be
|
177
|
-
#
|
178
|
-
# ```js
|
179
|
-
# return getItems();
|
180
|
-
# ```
|
181
|
-
#
|
182
|
-
# @return [nil]
|
183
|
-
def as_return!
|
184
|
-
@context.push(
|
185
|
-
type: 'ReturnStatement',
|
186
|
-
argument: @object
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
190
|
-
#
|
191
|
-
# Constructs a **MemberExpression**
|
192
|
-
#
|
193
|
-
# ```rb
|
194
|
-
# x = jsrb.var! :x
|
195
|
-
# obj = jsrb.expr['someObj']
|
196
|
-
# x.set! obj.member! 'field'
|
197
|
-
# ```
|
198
|
-
#
|
199
|
-
# will be
|
200
|
-
#
|
201
|
-
# ```js
|
202
|
-
# x = someObj['field'];
|
203
|
-
# ```
|
204
|
-
#
|
205
|
-
# @param [String, Symbol] value name of member
|
206
|
-
# @return [Jsrb::ExprChain] a chain represents **MemberExpression**
|
207
|
-
def member!(value)
|
208
85
|
if @object
|
209
86
|
self.class.new @context, type: 'MemberExpression',
|
210
87
|
computed: true,
|
@@ -217,26 +94,16 @@ module Jsrb
|
|
217
94
|
end
|
218
95
|
|
219
96
|
#
|
220
|
-
# Constructs a **AssignmentExpression** whose
|
221
|
-
#
|
222
|
-
# ```rb
|
223
|
-
# x = jsrb.var! :x
|
224
|
-
# y = jsrb.var! :y
|
225
|
-
# y.assign!(x.assign! 100).as_statement!
|
226
|
-
# ```
|
227
|
-
#
|
228
|
-
# will be
|
229
|
-
#
|
230
|
-
# ```js
|
231
|
-
# var x;
|
232
|
-
# var y;
|
233
|
-
# y = x = 100;
|
234
|
-
# ```
|
97
|
+
# Constructs a **AssignmentExpression** whose RHS is the current expression.
|
235
98
|
#
|
99
|
+
# @example
|
100
|
+
# x = js.expr[:x]
|
101
|
+
# y = js.expr[:y]
|
102
|
+
# y.set(x.set 100) # => ExprChain `x = y = 100`
|
236
103
|
# @param [Jsrb::ExprChain, convertible ruby values] value RHS value of assignment
|
237
104
|
# @return [Jsrb::ExprChain] a chain represents **AssignmentExpression**
|
238
|
-
def
|
239
|
-
raise ArgumentError, "Can't chain
|
105
|
+
def set(value)
|
106
|
+
raise ArgumentError, "Can't chain set on empty context" unless @object
|
240
107
|
|
241
108
|
self.class.new @context, type: 'AssignmentExpression',
|
242
109
|
operator: '=',
|
@@ -244,46 +111,15 @@ module Jsrb
|
|
244
111
|
right: @context.ruby_to_js_ast(value)
|
245
112
|
end
|
246
113
|
|
247
|
-
#
|
248
|
-
# Pushes an **ExpressionStatement** of the assignment expression.
|
249
|
-
#
|
250
|
-
# ```rb
|
251
|
-
# x = jsrb.var! :x
|
252
|
-
# x.set! 100
|
253
|
-
# ```
|
254
|
-
#
|
255
|
-
# will be
|
256
|
-
#
|
257
|
-
# ```js
|
258
|
-
# var x;
|
259
|
-
# x = 100;
|
260
|
-
# ```
|
261
|
-
#
|
262
|
-
# @param [Jsrb::ExprChain, convertible ruby values] value RHS value of assignment
|
263
|
-
# @return [nil]
|
264
|
-
def set!(value)
|
265
|
-
assign!(value).as_statement!
|
266
|
-
end
|
267
|
-
|
268
114
|
#
|
269
115
|
# Constructs a **CallExpression**.
|
270
116
|
#
|
271
|
-
#
|
272
|
-
#
|
273
|
-
#
|
274
|
-
#
|
275
|
-
# console.log.call('bar').as_statement!
|
276
|
-
# ```
|
277
|
-
#
|
278
|
-
# will be
|
279
|
-
#
|
280
|
-
# ```js
|
281
|
-
# console.log('foo');
|
282
|
-
# console.log('bar');
|
283
|
-
# ```
|
284
|
-
#
|
117
|
+
# @example
|
118
|
+
# console = js.expr[:console]
|
119
|
+
# console.log.('foo') # => ExprChain `console.log('foo')`
|
120
|
+
# console.log.call('bar') # => ExprChain `console.log('foo')`
|
285
121
|
# @param [Jsrb::ExprChain, convertible ruby values] args arguments
|
286
|
-
# @yield optional block
|
122
|
+
# @yield optional block as a final function argument
|
287
123
|
# @return [Jsrb::ExprChain] a chain represents **CallExpression**
|
288
124
|
def call(*args, &block)
|
289
125
|
raise ArgumentError, "Can't chain call on empty context" unless @object
|
@@ -300,21 +136,13 @@ module Jsrb
|
|
300
136
|
#
|
301
137
|
# Constructs a **NewExpression**.
|
302
138
|
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
# ```
|
307
|
-
#
|
308
|
-
# will be
|
309
|
-
#
|
310
|
-
# ```js
|
311
|
-
# x = new Date;
|
312
|
-
# ```
|
313
|
-
#
|
139
|
+
# @example
|
140
|
+
# js.expr[:Date].new # => ExprChain `new Date`
|
141
|
+
# js.expr[:Date].new(2020, 1, 1) # => ExprChain `new Date(2020, 1, 1)`
|
314
142
|
# @param [Jsrb::ExprChain, convertible ruby values] args arguments
|
315
143
|
# @return [Jsrb::ExprChain] a chain represents **NewExpression**
|
316
|
-
def new
|
317
|
-
raise ArgumentError, "Can't chain new
|
144
|
+
def new(*args)
|
145
|
+
raise ArgumentError, "Can't chain new on empty context" unless @object
|
318
146
|
|
319
147
|
arguments = args.map do |arg|
|
320
148
|
@context.ruby_to_js_ast(arg)
|
@@ -329,29 +157,21 @@ module Jsrb
|
|
329
157
|
#
|
330
158
|
# All ruby-overridable operators can also be used:
|
331
159
|
# `** + - * / % >> << & ^ | <= < > >= == === != ! && ||`
|
332
|
-
#
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
# ```
|
337
|
-
#
|
338
|
-
# will be
|
339
|
-
#
|
340
|
-
# ```js
|
341
|
-
# x = a < 100;
|
342
|
-
# ```
|
343
|
-
#
|
160
|
+
# @example
|
161
|
+
# (js.expr[:n] < 100) # => ExprChain `n < 100`
|
162
|
+
# !(js.expr[:b]) # => ExprChain `!b`
|
163
|
+
# js.expr[:a].op('||', 'default') # => ExprChain `a || 'default'`
|
344
164
|
# @param [String, Symbol] operator operator
|
345
|
-
# @param
|
165
|
+
# @param [Jsrb::ExprChain, convertible ruby values] args RHS value for binary operators
|
346
166
|
# @return [Jsrb::ExprChain] a chain represents **UnaryExpression**, **BinaryExpression** or **LogicalExpression**
|
347
|
-
def op
|
348
|
-
raise ArgumentError, "Can't chain op
|
167
|
+
def op(operator, *args)
|
168
|
+
raise ArgumentError, "Can't chain op on empty context" unless @object
|
349
169
|
|
350
170
|
opstr = operator.to_s
|
351
171
|
if args.size == 1
|
352
|
-
_binary_op
|
172
|
+
_binary_op(opstr, *args)
|
353
173
|
elsif args.empty?
|
354
|
-
_unary_op
|
174
|
+
_unary_op(opstr)
|
355
175
|
else
|
356
176
|
raise ArgumentError, "#{opstr} is not a valid operator"
|
357
177
|
end
|
@@ -359,11 +179,11 @@ module Jsrb
|
|
359
179
|
|
360
180
|
%i[** + - * / % >> << & ^ | <= < > >= == === != !].each do |operator|
|
361
181
|
define_method(operator) do |*args|
|
362
|
-
op
|
182
|
+
op(operator, *args)
|
363
183
|
end
|
364
184
|
end
|
365
185
|
|
366
|
-
private def _binary_op
|
186
|
+
private def _binary_op(opstr, arg)
|
367
187
|
if JS_LOGICAL_OPS.include? opstr
|
368
188
|
self.class.new @context, type: 'LogicalExpression',
|
369
189
|
operator: opstr,
|
@@ -377,7 +197,7 @@ module Jsrb
|
|
377
197
|
end
|
378
198
|
end
|
379
199
|
|
380
|
-
private def _unary_op
|
200
|
+
private def _unary_op(opstr)
|
381
201
|
self.class.new @context, type: 'UnaryExpression',
|
382
202
|
operator: opstr,
|
383
203
|
argument: @object,
|
@@ -387,17 +207,8 @@ module Jsrb
|
|
387
207
|
#
|
388
208
|
# Constructs a **ConditionalExpression** whose test expression is the current expression.
|
389
209
|
#
|
390
|
-
#
|
391
|
-
#
|
392
|
-
# x.set! (jsrb.expr['height'] < 300).cond?('lo', 'hi')
|
393
|
-
# ```
|
394
|
-
#
|
395
|
-
# will be
|
396
|
-
#
|
397
|
-
# ```js
|
398
|
-
# x = (height < 300) ? 'lo' : 'hi';
|
399
|
-
# ```
|
400
|
-
#
|
210
|
+
# @example
|
211
|
+
# (js.expr[:height] < 300).cond?('lo', 'hi') # => ExprChain `(height < 300) ? 'lo' : 'hi'`
|
401
212
|
# @param [Jsrb::ExprChain, convertible ruby values] consequent expression used in consequent
|
402
213
|
# @param [Jsrb::ExprChain, convertible ruby values] alternate expression used in alternate
|
403
214
|
# @return [Jsrb::ExprChain] a chain represents **ConditionalExpression**
|
@@ -413,21 +224,12 @@ module Jsrb
|
|
413
224
|
#
|
414
225
|
# Constructs a **FunctionExpression** whose returned body is the current context.
|
415
226
|
#
|
416
|
-
#
|
417
|
-
#
|
418
|
-
# f.set! (jsrb.expr['x'] * 2).for_all(:x)
|
419
|
-
# ```
|
420
|
-
#
|
421
|
-
# will be
|
422
|
-
#
|
423
|
-
# ```js
|
424
|
-
# f = function (x) { return x * 2; };
|
425
|
-
# ```
|
426
|
-
#
|
227
|
+
# @example
|
228
|
+
# (js.expr[:x] * 2).forall(:x) # => ExprChain `function (x) { return x * 2; }`
|
427
229
|
# @param [String, Symbol] args argument identifiers
|
428
230
|
# @return [Jsrb::ExprChain] a chain represents **FunctionExpression**
|
429
|
-
def
|
430
|
-
raise ArgumentError, "Can't chain
|
231
|
+
def forall(*args)
|
232
|
+
raise ArgumentError, "Can't chain forall on empty context" unless @object
|
431
233
|
|
432
234
|
self.class.new @context, type: 'FunctionExpression',
|
433
235
|
id: nil,
|
@@ -448,8 +250,10 @@ module Jsrb
|
|
448
250
|
}
|
449
251
|
end
|
450
252
|
|
451
|
-
|
452
|
-
|
253
|
+
# Internal method for custom chains.
|
254
|
+
# @private
|
255
|
+
def _bind_chain!(function_name, *args, &block)
|
256
|
+
raise ArgumentError, "Can't _bind_chain! on empty context" unless @object
|
453
257
|
|
454
258
|
arg_asts = [@object]
|
455
259
|
args.each do |arg|
|
@@ -457,7 +261,7 @@ module Jsrb
|
|
457
261
|
end
|
458
262
|
arg_asts << @context.ruby_to_js_ast(block) if block_given?
|
459
263
|
self.class.new @context, type: 'CallExpression',
|
460
|
-
callee: self.class.new(@context)
|
264
|
+
callee: self.class.new(@context)[function_name].object,
|
461
265
|
arguments: arg_asts
|
462
266
|
end
|
463
267
|
|
@@ -465,18 +269,10 @@ module Jsrb
|
|
465
269
|
#
|
466
270
|
# Adds a new chain method.
|
467
271
|
#
|
468
|
-
#
|
469
|
-
#
|
470
|
-
#
|
471
|
-
# jsrb.expr['foo']['bar'].log_here.as_statement!
|
472
|
-
# ```
|
473
|
-
#
|
474
|
-
# will be
|
475
|
-
#
|
476
|
-
# ```js
|
477
|
-
# __tap_log__(foo['bar']);
|
478
|
-
# ```
|
272
|
+
# @example
|
273
|
+
# Jsrb::ExprChain.add_custom_chain('log_here', '__tap_log__')
|
479
274
|
#
|
275
|
+
# js.expr[:foo][:bar].log_here # => ExprChain `__tap_log__(foo['bar'])`
|
480
276
|
# @param [Symbol] chain_method_name name of a chain method
|
481
277
|
# @param [Symbol] function_name name of wrapper function
|
482
278
|
def add_custom_chain(chain_method_name, function_name)
|
@@ -484,9 +280,8 @@ module Jsrb
|
|
484
280
|
@_custom_chains[chain_method_name] = function_name
|
485
281
|
end
|
486
282
|
|
487
|
-
#
|
488
283
|
# Show custom chains.
|
489
|
-
#
|
284
|
+
# @private
|
490
285
|
def custom_chains
|
491
286
|
@_custom_chains || {}
|
492
287
|
end
|