opal 0.3.26 → 0.3.27
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.
- data/.gitignore +1 -6
- data/.travis.yml +1 -4
- data/Gemfile +1 -1
- data/README.md +3 -8
- data/Rakefile +26 -3
- data/core/array.rb +33 -91
- data/core/boolean.rb +1 -4
- data/core/class.rb +25 -71
- data/core/error.rb +5 -3
- data/core/hash.rb +3 -2
- data/core/kernel.rb +40 -1
- data/core/load_order +1 -1
- data/core/nil_class.rb +1 -3
- data/core/runtime.js +4 -44
- data/core/template.rb +20 -0
- data/core/{opal-spec → test_runner}/runner.js +0 -6
- data/lib/opal.rb +1 -12
- data/lib/opal/builder.rb +3 -10
- data/lib/opal/lexer.rb +1095 -1110
- data/lib/opal/parser.rb +229 -26
- data/lib/opal/rake_task.rb +3 -3
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +2 -2
- data/spec/core/array/assoc_spec.rb +2 -3
- data/spec/core/array/comparison_spec.rb +16 -0
- data/spec/core/array/constructor_spec.rb +0 -9
- data/spec/core/array/drop_spec.rb +21 -0
- data/spec/core/array/dup_spec.rb +15 -0
- data/spec/core/array/{eql_spec.rb → equal_value_spec.rb} +0 -0
- data/spec/core/array/index_spec.rb +26 -0
- data/spec/core/array/inspect_spec.rb +13 -0
- data/spec/core/array/intersection_spec.rb +22 -0
- data/spec/core/array/join_spec.rb +9 -0
- data/spec/core/array/keep_if_spec.rb +7 -0
- data/spec/core/array/minus_spec.rb +19 -9
- data/spec/core/array/multiply_spec.rb +13 -0
- data/spec/core/array/new_spec.rb +40 -0
- data/spec/core/array/rindex_spec.rb +21 -0
- data/spec/core/array/select_spec.rb +13 -0
- data/spec/core/array/shift_spec.rb +51 -0
- data/spec/core/array/slice_spec.rb +37 -0
- data/spec/core/array/take_spec.rb +21 -0
- data/spec/core/array/take_while_spec.rb +13 -0
- data/spec/core/array/to_a_spec.rb +7 -0
- data/spec/core/array/unshift_spec.rb +29 -0
- data/spec/core/hash/constructor_spec.rb +13 -0
- data/spec/core/hash/default_proc_spec.rb +20 -0
- data/spec/core/hash/default_spec.rb +8 -0
- data/spec/core/hash/delete_spec.rb +11 -0
- data/spec/core/hash/dup_spec.rb +10 -0
- data/spec/core/hash/reject_spec.rb +18 -0
- data/spec/core/hash/to_a_spec.rb +13 -0
- data/spec/core/kernel/Array_spec.rb +10 -0
- data/spec/core/kernel/class_spec.rb +6 -0
- data/spec/core/kernel/equal_spec.rb +12 -0
- data/spec/core/kernel/extend_spec.rb +21 -0
- data/spec/core/kernel/instance_eval_spec.rb +28 -0
- data/spec/core/kernel/instance_variable_get_spec.rb +14 -0
- data/spec/core/kernel/instance_variable_set_spec.rb +10 -0
- data/spec/core/kernel/match_spec.rb +5 -0
- data/spec/core/module/alias_method_spec.rb +10 -0
- data/spec/core/module/ancestors_spec.rb +11 -0
- data/spec/core/module/append_features_spec.rb +14 -0
- data/spec/core/proc/call_spec.rb +21 -0
- data/spec/core/proc/proc_tricks_spec.rb +1 -1
- data/spec/language/alias_spec.rb +1 -1
- data/spec/opal/class/instance_methods_spec.rb +13 -0
- data/spec/opal/kernel/attribute_spec.rb +57 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/test_case.html +13 -0
- metadata +88 -12
- data/core/erb.rb +0 -32
- data/lib/opal/erb_parser.rb +0 -20
- data/spec/opal/erb/erb_spec.rb +0 -23
data/lib/opal/parser.rb
CHANGED
@@ -3,12 +3,52 @@ require 'opal/grammar'
|
|
3
3
|
require 'opal/scope'
|
4
4
|
|
5
5
|
module Opal
|
6
|
-
|
6
|
+
# This class is used to generate the javascript code from the given
|
7
|
+
# ruby code. First, this class will use an instance of `Opal::Grammar`
|
8
|
+
# to lex and then build up a tree of sexp statements. Once done, the
|
9
|
+
# top level sexp is passed into `#top` which recursively generates
|
10
|
+
# javascript for each sexp inside, and the result is returned as a
|
11
|
+
# string.
|
12
|
+
#
|
13
|
+
# p = Opal::Parser.new
|
14
|
+
# p.parse "puts 42"
|
15
|
+
# # => "(function() { ... })()"
|
16
|
+
#
|
17
|
+
# ## Sexps
|
18
|
+
#
|
19
|
+
# A sexp, in opal, is an array where the first value is a symbol
|
20
|
+
# identifying the type of sexp. A simple ruby string "hello" would
|
21
|
+
# be represented by the sexp:
|
22
|
+
#
|
23
|
+
# s(:str, "hello")
|
24
|
+
#
|
25
|
+
# Once that sexp is encounterd by the parser, it is handled by
|
26
|
+
# `#process` which removes the sexp type from the array, and checks
|
27
|
+
# for a method "process_str", which is used to handle specific sexps.
|
28
|
+
# Once found, that method is called with the sexp and level as
|
29
|
+
# arguments, and the returned string is the javascript to be used in
|
30
|
+
# the resulting file.
|
31
|
+
#
|
32
|
+
# ## Levels
|
33
|
+
#
|
34
|
+
# A level inside the parser is just a symbol representing what type
|
35
|
+
# of destination the code to be generated is for. For example, the
|
36
|
+
# main two levels are `:stmt` and `:expr`. Most sexps generate the
|
37
|
+
# same code for every level, but an `if` statement for example
|
38
|
+
# will change when written as an expression. Javascript cannot have
|
39
|
+
# if statements as expressions, so that sexp would wrap its result
|
40
|
+
# inside an anonymous function so the if statement can compile as
|
41
|
+
# expected.
|
7
42
|
class Parser
|
43
|
+
# Generated code gets indented with two spaces on each scope
|
8
44
|
INDENT = ' '
|
9
45
|
|
46
|
+
# Expressions are handled at diffferent levels. Some sexps
|
47
|
+
# need to know the js expression they are generating into.
|
10
48
|
LEVEL = [:stmt, :stmt_closure, :list, :expr, :recv]
|
11
49
|
|
50
|
+
# All compare method nodes - used to optimize performance of
|
51
|
+
# math comparisons
|
12
52
|
COMPARE = %w[< > <= >=]
|
13
53
|
|
14
54
|
# Reserved javascript keywords - we cannot create variables with the
|
@@ -20,16 +60,32 @@ module Opal
|
|
20
60
|
const
|
21
61
|
)
|
22
62
|
|
63
|
+
# Statements which should not have ';' added to them.
|
23
64
|
STATEMENTS = [:xstr, :dxstr]
|
24
65
|
|
66
|
+
# The grammar (tree of sexps) representing this compiled code
|
67
|
+
# @return [Opal::Grammar]
|
25
68
|
attr_reader :grammar
|
26
69
|
|
70
|
+
# Holds an array of paths which this file "requires".
|
71
|
+
# @return [Array<String>]
|
27
72
|
attr_reader :requires
|
28
73
|
|
74
|
+
# This does the actual parsing. The ruby code given is first
|
75
|
+
# run through a `Grammar` instance which returns a sexp to
|
76
|
+
# process. This is then handled recursively, resulting in a
|
77
|
+
# string of javascript being returned.
|
78
|
+
#
|
79
|
+
# p = Opal::Parser.new
|
80
|
+
# p.parse "puts 'hey'"
|
81
|
+
# # => "(function() { .... })()"
|
82
|
+
#
|
83
|
+
# @param [String] source the ruby code to parse
|
84
|
+
# @param [String] file the filename representing this code
|
85
|
+
# @return [String] string of javascript code
|
29
86
|
def parse(source, file = '(file)')
|
30
87
|
@grammar = Grammar.new
|
31
88
|
@requires = []
|
32
|
-
@comments = false
|
33
89
|
@file = file
|
34
90
|
@line = 1
|
35
91
|
@indent = ''
|
@@ -43,24 +99,54 @@ module Opal
|
|
43
99
|
top @grammar.parse(source, file)
|
44
100
|
end
|
45
101
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
102
|
+
# This is called when a parsing/processing error occurs. This
|
103
|
+
# method simply appends the filename and curent line number onto
|
104
|
+
# the message and raises it.
|
105
|
+
#
|
106
|
+
# parser.error "bad variable name"
|
107
|
+
# # => raise "bad variable name :foo.rb:26"
|
108
|
+
#
|
109
|
+
# @param [String] msg error message to raise
|
50
110
|
def error(msg)
|
51
111
|
raise "#{msg} :#{@file}:#{@line}"
|
52
112
|
end
|
53
113
|
|
114
|
+
# Instances of `Scope` can use this to determine the current
|
115
|
+
# scope indent. The indent is used to keep generated code easily
|
116
|
+
# readable.
|
117
|
+
#
|
118
|
+
# @return [String]
|
54
119
|
def parser_indent
|
55
120
|
@indent
|
56
121
|
end
|
57
122
|
|
123
|
+
# Create a new sexp using the given parts. Even though this just
|
124
|
+
# returns an array, it must be used incase the internal structure
|
125
|
+
# of sexps does change.
|
126
|
+
#
|
127
|
+
# s(:str, "hello there")
|
128
|
+
# # => [:str, "hello there"]
|
129
|
+
#
|
130
|
+
# @result [Array]
|
58
131
|
def s(*parts)
|
59
132
|
sexp = Sexp.new(parts)
|
60
133
|
sexp.line = @line
|
61
134
|
sexp
|
62
135
|
end
|
63
136
|
|
137
|
+
# Converts a ruby method name into its javascript equivalent for
|
138
|
+
# a method/function call. All ruby method names get prefixed with
|
139
|
+
# a '$', and if the name is a valid javascript identifier, it will
|
140
|
+
# have a '.' prefix (for dot-calling), otherwise it will be
|
141
|
+
# wrapped in brackets to use reference notation calling.
|
142
|
+
#
|
143
|
+
# mid_to_jsid('foo') # => ".$foo"
|
144
|
+
# mid_to_jsid('class') # => ".$class"
|
145
|
+
# mid_to_jsid('==') # => "['$==']"
|
146
|
+
# mid_to_jsid('name=') # => "['$name=']"
|
147
|
+
#
|
148
|
+
# @param [String] mid ruby method id
|
149
|
+
# @return [String]
|
64
150
|
def mid_to_jsid(mid)
|
65
151
|
if /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
|
66
152
|
"['$#{mid}']"
|
@@ -69,11 +155,21 @@ module Opal
|
|
69
155
|
end
|
70
156
|
end
|
71
157
|
|
72
|
-
#
|
158
|
+
# Used to generate a unique id name per file. These are used
|
159
|
+
# mainly to name method bodies for methods that use blocks.
|
160
|
+
#
|
161
|
+
# @return [String]
|
73
162
|
def unique_temp
|
74
163
|
"TMP_#{@unique += 1}"
|
75
164
|
end
|
76
165
|
|
166
|
+
# Generate the code for the top level sexp, i.e. the root sexp
|
167
|
+
# for a file. This is used directly by `#parse`. It pushes a
|
168
|
+
# ":top" scope onto the stack and handles the passed in sexp.
|
169
|
+
# The result is a string of javascript representing the sexp.
|
170
|
+
#
|
171
|
+
# @param [Array] sexp the sexp to process
|
172
|
+
# @return [String]
|
77
173
|
def top(sexp, options = {})
|
78
174
|
code = nil
|
79
175
|
vars = []
|
@@ -93,9 +189,29 @@ module Opal
|
|
93
189
|
code = "#{INDENT}var #{vars.join ', '};\n" + INDENT + @scope.to_vars + "\n" + code
|
94
190
|
end
|
95
191
|
|
96
|
-
"function() {\n#{ code }\n}"
|
192
|
+
"(function() {\n#{ code }\n})();"
|
97
193
|
end
|
98
194
|
|
195
|
+
# Every time the parser enters a new scope, this is called with
|
196
|
+
# the scope type as an argument. Valid types are `:top` for the
|
197
|
+
# top level/file scope; `:class`, `:module` and `:sclass` for the
|
198
|
+
# obvious ruby classes/modules; `:def` and `:iter` for methods
|
199
|
+
# and blocks respectively.
|
200
|
+
#
|
201
|
+
# This method just pushes a new instance of `Opal::Scope` onto the
|
202
|
+
# stack, sets the new scope as the `@scope` variable, and yields
|
203
|
+
# the given block. Once the block returns, the old scope is put
|
204
|
+
# back on top of the stack.
|
205
|
+
#
|
206
|
+
# in_scope(:class) do
|
207
|
+
# # generate class body in here
|
208
|
+
# body = "..."
|
209
|
+
# end
|
210
|
+
#
|
211
|
+
# # use body result..
|
212
|
+
#
|
213
|
+
# @param [Symbol] type the type of scope
|
214
|
+
# @return [nil]
|
99
215
|
def in_scope(type)
|
100
216
|
return unless block_given?
|
101
217
|
|
@@ -106,6 +222,15 @@ module Opal
|
|
106
222
|
@scope = parent
|
107
223
|
end
|
108
224
|
|
225
|
+
# To keep code blocks nicely indented, this will yield a block after
|
226
|
+
# adding an extra layer of indent, and then returning the resulting
|
227
|
+
# code after reverting the indent.
|
228
|
+
#
|
229
|
+
# indented_code = indent do
|
230
|
+
# "foo"
|
231
|
+
# end
|
232
|
+
#
|
233
|
+
# @result [String]
|
109
234
|
def indent(&block)
|
110
235
|
indent = @indent
|
111
236
|
@indent += INDENT
|
@@ -116,6 +241,17 @@ module Opal
|
|
116
241
|
res
|
117
242
|
end
|
118
243
|
|
244
|
+
# Temporary varibales will be needed from time to time in the
|
245
|
+
# generated code, and this method will assign (or reuse) on
|
246
|
+
# while the block is yielding, and queue it back up once it is
|
247
|
+
# finished. Variables are queued once finished with to save the
|
248
|
+
# numbers of variables needed at runtime.
|
249
|
+
#
|
250
|
+
# with_temp do |tmp|
|
251
|
+
# "tmp = 'value';"
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# @return [String] generated code withing block
|
119
255
|
def with_temp(&block)
|
120
256
|
tmp = @scope.new_temp
|
121
257
|
res = yield tmp
|
@@ -123,12 +259,6 @@ module Opal
|
|
123
259
|
res
|
124
260
|
end
|
125
261
|
|
126
|
-
# Should be overriden in custom parsers to handle a require
|
127
|
-
# statement.
|
128
|
-
def handle_require(arglist)
|
129
|
-
"/* require statement removed */"
|
130
|
-
end
|
131
|
-
|
132
262
|
# Used when we enter a while statement. This pushes onto the current
|
133
263
|
# scope's while stack so we know how to handle break, next etc.
|
134
264
|
#
|
@@ -146,10 +276,28 @@ module Opal
|
|
146
276
|
result
|
147
277
|
end
|
148
278
|
|
279
|
+
# Returns true if the parser is curently handling a while sexp,
|
280
|
+
# false otherwise.
|
281
|
+
#
|
282
|
+
# @return [Boolean]
|
149
283
|
def in_while?
|
150
284
|
@scope.in_while?
|
151
285
|
end
|
152
286
|
|
287
|
+
# Processes a given sexp. This will send a method to the receiver
|
288
|
+
# of the format "process_<sexp_name>". Any sexp handler should
|
289
|
+
# return a string of content.
|
290
|
+
#
|
291
|
+
# For example, calling `process` with `s(:lit, 42)` will call the
|
292
|
+
# method `#process_lit`. If a method with that name cannot be
|
293
|
+
# found, then an error is raised.
|
294
|
+
#
|
295
|
+
# process(s(:lit, 42), :stmt)
|
296
|
+
# # => "42"
|
297
|
+
#
|
298
|
+
# @param [Array] sexp the sexp to process
|
299
|
+
# @param [Symbol] level the level to process (see `LEVEL`)
|
300
|
+
# @return [String]
|
153
301
|
def process(sexp, level)
|
154
302
|
type = sexp.shift
|
155
303
|
meth = "process_#{type}"
|
@@ -160,6 +308,27 @@ module Opal
|
|
160
308
|
__send__ meth, sexp, level
|
161
309
|
end
|
162
310
|
|
311
|
+
# The last sexps in method bodies, for example, need to be returned
|
312
|
+
# in the compiled javascript. Due to syntax differences between
|
313
|
+
# javascript any ruby, some sexps need to be handled specially. For
|
314
|
+
# example, `if` statemented cannot be returned in javascript, so
|
315
|
+
# instead the "truthy" and "falsy" parts of the if statement both
|
316
|
+
# need to be returned instead.
|
317
|
+
#
|
318
|
+
# Sexps that need to be returned are passed to this method, and the
|
319
|
+
# alterned/new sexps are returned and should be used instead. Most
|
320
|
+
# sexps can just be added into a s(:return) sexp, so that is the
|
321
|
+
# default action if no special case is required.
|
322
|
+
#
|
323
|
+
# sexp = s(:str, "hey")
|
324
|
+
# parser.returns(sexp)
|
325
|
+
# # => s(:js_return, s(:str, "hey"))
|
326
|
+
#
|
327
|
+
# `s(:js_return)` is just a special sexp used to return the result
|
328
|
+
# of processing its arguments.
|
329
|
+
#
|
330
|
+
# @param [Array] sexp the sexp to alter
|
331
|
+
# @return [Array] altered sexp
|
163
332
|
def returns(sexp)
|
164
333
|
return returns s(:nil) unless sexp
|
165
334
|
|
@@ -206,10 +375,28 @@ module Opal
|
|
206
375
|
end
|
207
376
|
end
|
208
377
|
|
378
|
+
# Returns true if the given sexp is an expression. All expressions
|
379
|
+
# will get ';' appended to their result, except for the statement
|
380
|
+
# sexps. See `STATEMENTS` for a list of sexp names that are
|
381
|
+
# statements.
|
382
|
+
#
|
383
|
+
# @param [Array] sexp the sexp to check
|
384
|
+
# @return [Boolean]
|
209
385
|
def expression?(sexp)
|
210
386
|
!STATEMENTS.include?(sexp.first)
|
211
387
|
end
|
212
388
|
|
389
|
+
# More than one expression in a row will be grouped by the grammar
|
390
|
+
# into a block sexp. A block sexp just holds any number of other
|
391
|
+
# sexps.
|
392
|
+
#
|
393
|
+
# s(:block, s(:str, "hey"), s(:lit, 42))
|
394
|
+
#
|
395
|
+
# A block can actually be empty. As opal requires real values to
|
396
|
+
# be returned (to appease javascript values), a nil sexp
|
397
|
+
# s(:nil) will be generated if the block is empty.
|
398
|
+
#
|
399
|
+
# @return [String]
|
213
400
|
def process_block(sexp, level)
|
214
401
|
result = []
|
215
402
|
sexp << s(:nil) if sexp.empty?
|
@@ -231,6 +418,27 @@ module Opal
|
|
231
418
|
result.join(@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
|
232
419
|
end
|
233
420
|
|
421
|
+
# When a block sexp gets generated, any inline yields (i.e. yield
|
422
|
+
# statements that are not direct members of the block) need to be
|
423
|
+
# generated as a top level member. This is because if a yield
|
424
|
+
# is returned by a break statement, then the method must return.
|
425
|
+
#
|
426
|
+
# As inline expressions in javascript cannot return, the block
|
427
|
+
# must be rewritten.
|
428
|
+
#
|
429
|
+
# For example, a yield inside an array:
|
430
|
+
#
|
431
|
+
# [1, 2, 3, yield(4)]
|
432
|
+
#
|
433
|
+
# Must be rewitten into:
|
434
|
+
#
|
435
|
+
# tmp = yield 4
|
436
|
+
# [1, 2, 3, tmp]
|
437
|
+
#
|
438
|
+
# This rewriting happens on sexps directly.
|
439
|
+
#
|
440
|
+
# @param [Sexp] stmt sexps to (maybe) rewrite
|
441
|
+
# @return [Sexp]
|
234
442
|
def find_inline_yield(stmt)
|
235
443
|
found = nil
|
236
444
|
case stmt.first
|
@@ -415,12 +623,12 @@ module Opal
|
|
415
623
|
args ||= s(:masgn, s(:array))
|
416
624
|
args = args.first == :lasgn ? s(:array, args) : args[1]
|
417
625
|
|
418
|
-
if args.last[0] == :block_pass
|
626
|
+
if args.last.is_a?(Array) and args.last[0] == :block_pass
|
419
627
|
block_arg = args.pop
|
420
628
|
block_arg = block_arg[1][1].to_sym
|
421
629
|
end
|
422
630
|
|
423
|
-
if args.last[0] == :splat
|
631
|
+
if args.last.is_a?(Array) and args.last[0] == :splat
|
424
632
|
splat = args.last[1][1]
|
425
633
|
args.pop
|
426
634
|
len = args.length
|
@@ -509,7 +717,7 @@ module Opal
|
|
509
717
|
# @param [Symbol] meth :attr_{reader,writer,accessor}
|
510
718
|
# @param [Array<Sexp>] attrs array of s(:lit) or s(:str)
|
511
719
|
# @return [String] precompiled attr methods
|
512
|
-
def
|
720
|
+
def handle_attr_optimize(meth, attrs)
|
513
721
|
out = []
|
514
722
|
|
515
723
|
attrs.each do |attr|
|
@@ -555,16 +763,12 @@ module Opal
|
|
555
763
|
|
556
764
|
case meth
|
557
765
|
when :attr_reader, :attr_writer, :attr_accessor
|
558
|
-
|
559
|
-
if @scope.class_scope? && attrs.all? { |a| [:lit, :str].include? a.first }
|
560
|
-
return attr_optimize meth, attrs
|
561
|
-
end
|
766
|
+
return handle_attr_optimize(meth, arglist[1..-1])
|
562
767
|
when :block_given?
|
563
768
|
return js_block_given(sexp, level)
|
564
769
|
when :alias_native
|
565
770
|
return handle_alias_native(sexp) if @scope.class_scope?
|
566
771
|
when :require
|
567
|
-
# return handle_require(arglist)
|
568
772
|
path = arglist[1]
|
569
773
|
|
570
774
|
if path and path[0] == :str
|
@@ -699,7 +903,7 @@ module Opal
|
|
699
903
|
spacer = "\n#{@indent}#{INDENT}"
|
700
904
|
cls = "function #{name}() {};"
|
701
905
|
boot = "#{name} = __klass(__base, __super, #{name.inspect}, #{name});"
|
702
|
-
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, class #{ name }"
|
906
|
+
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, class #{ name }"
|
703
907
|
|
704
908
|
"(function(__base, __super){#{comment}#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base}, #{sup})"
|
705
909
|
end
|
@@ -753,7 +957,7 @@ module Opal
|
|
753
957
|
spacer = "\n#{@indent}#{INDENT}"
|
754
958
|
cls = "function #{name}() {};"
|
755
959
|
boot = "#{name} = __module(__base, #{name.inspect}, #{name});"
|
756
|
-
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, module #{ name }"
|
960
|
+
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, module #{ name }"
|
757
961
|
|
758
962
|
"(function(__base){#{comment}#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base})"
|
759
963
|
end
|
@@ -808,7 +1012,7 @@ module Opal
|
|
808
1012
|
|
809
1013
|
# block name &block
|
810
1014
|
if args.last.to_s.start_with? '&'
|
811
|
-
block_name = args.pop[1..-1].to_sym
|
1015
|
+
block_name = args.pop.to_s[1..-1].to_sym
|
812
1016
|
end
|
813
1017
|
|
814
1018
|
# splat args *splat
|
@@ -874,7 +1078,6 @@ module Opal
|
|
874
1078
|
end
|
875
1079
|
|
876
1080
|
comment += "\n#{@indent}"
|
877
|
-
comment = nil unless @comments
|
878
1081
|
|
879
1082
|
if recvr
|
880
1083
|
if smethod
|
data/lib/opal/rake_task.rb
CHANGED
@@ -15,7 +15,7 @@ module Opal
|
|
15
15
|
@dir = @project_dir
|
16
16
|
@build_dir = 'build'
|
17
17
|
@specs_dir = 'spec'
|
18
|
-
@files = Dir['lib/**/*.
|
18
|
+
@files = Dir['lib/**/*.rb']
|
19
19
|
@dependencies = []
|
20
20
|
|
21
21
|
yield self if block_given?
|
@@ -67,9 +67,9 @@ module Opal
|
|
67
67
|
@dependencies.each { |dep| build_gem dep }
|
68
68
|
end
|
69
69
|
|
70
|
-
desc "Run
|
70
|
+
desc "Run specs in spec/index.html"
|
71
71
|
task 'opal:test' do
|
72
|
-
runner = File.join
|
72
|
+
runner = File.join Opal.core_dir, 'test_runner', 'runner.js'
|
73
73
|
sh "phantomjs #{runner} spec/index.html"
|
74
74
|
end
|
75
75
|
|
data/lib/opal/version.rb
CHANGED