opal 0.3.44 → 0.4.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.
- data/.travis.yml +0 -1
- data/CHANGELOG.md +52 -0
- data/README.md +3 -3
- data/Rakefile +32 -8
- data/bin/opal +69 -16
- data/config.ru +1 -1
- data/examples/native/app/app.rb +28 -9
- data/examples/rack/app/app.rb +1 -1
- data/lib/opal.rb +0 -1
- data/lib/opal/cli.rb +106 -0
- data/lib/opal/lexer.rb +4 -2
- data/lib/opal/parser.rb +603 -360
- data/lib/opal/processor.rb +20 -8
- data/lib/opal/server.rb +47 -0
- data/lib/opal/source_map.rb +63 -0
- data/lib/opal/sprockets_parser.rb +77 -0
- data/lib/opal/sprockets_source_map_header.rb +21 -0
- data/lib/opal/target_scope.rb +14 -7
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +2 -0
- data/opal/opal-browser/script_loader.rb +7 -7
- data/opal/opal-parser.js.erb +2 -2
- data/opal/opal-source-maps.js.erb +2 -0
- data/opal/opal.rb +3 -4
- data/opal/opal/array.rb +31 -28
- data/opal/opal/boolean.rb +4 -0
- data/opal/opal/class.rb +14 -5
- data/opal/opal/enumerable.rb +68 -8
- data/opal/opal/error.rb +1 -1
- data/opal/opal/hash.rb +15 -18
- data/opal/opal/kernel.rb +24 -10
- data/opal/opal/native.rb +31 -0
- data/opal/opal/nil_class.rb +7 -2
- data/opal/opal/numeric.rb +10 -1
- data/opal/opal/proc.rb +4 -0
- data/opal/opal/range.rb +1 -1
- data/opal/opal/regexp.rb +13 -3
- data/opal/opal/runtime.js +134 -51
- data/opal/opal/string.rb +45 -22
- data/opal/opal/time.rb +25 -7
- data/opal/source_map.rb +63 -0
- data/opal/source_map/generator.rb +251 -0
- data/opal/source_map/parser.rb +102 -0
- data/opal/source_map/vlq.rb +122 -0
- data/opal/strscan.rb +30 -12
- data/spec/opal/class/_inherited_spec.rb +1 -1
- data/spec/{rubyspec/core → opal}/class/bridge_class_spec.rb +5 -3
- data/spec/{rubyspec/core → opal}/class/extend_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/class/instance_methods_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/class/last_value_spec.rb +0 -1
- data/spec/{rubyspec/core → opal}/json/parse_spec.rb +0 -0
- data/spec/{rubyspec/core/kernel/block_given.rb → opal/kernel/block_given_spec.rb} +0 -0
- data/spec/{rubyspec/core → opal}/kernel/class_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/extend_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/format_spec.rb +0 -0
- data/spec/opal/kernel/freeze_spec.rb +15 -0
- data/spec/{rubyspec/core → opal}/kernel/match_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/method_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/methods_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/nil_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/p_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/printf_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/proc_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/rand_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/respond_to_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/sprintf_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/kernel/to_json_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/module/alias_method_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/module/ancestors_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/module/append_features_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/module/constants_spec.rb +0 -0
- data/spec/{rubyspec/core → opal}/module/module_function_spec.rb +0 -1
- data/spec/opal/native_spec.rb +85 -3
- data/spec/opal/numeric/equal_spec.rb +9 -0
- data/spec/opal/parser/irb_spec.rb +43 -0
- data/spec/{rubyspec/core → opal}/proc/proc_tricks_spec.rb +0 -0
- data/spec/opal/runtime/block_send_spec.rb +28 -0
- data/spec/{rubyspec/core/runtime → opal/runtime2}/call_spec.rb +0 -0
- data/spec/{rubyspec/core/runtime → opal/runtime2}/class_hierarchy_spec.rb +0 -0
- data/spec/{rubyspec/core/runtime → opal/runtime2}/def_spec.rb +0 -0
- data/spec/{rubyspec/core/runtime → opal/runtime2}/defined_spec.rb +0 -0
- data/spec/{rubyspec/core/runtime → opal/runtime2}/super_spec.rb +0 -0
- data/spec/opal/source_map_spec.rb +19 -0
- data/spec/opal/string/freeze_spec.rb +15 -0
- data/spec/{rubyspec/core → opal}/string/to_json_spec.rb +0 -0
- data/spec/ospec/runner.rb +3 -0
- data/spec/parser/str_spec.rb +4 -0
- data/spec/rubyspec/core/enumerable/fixtures/classes.rb +2 -2
- data/spec/rubyspec/core/enumerable/none_spec.rb +68 -0
- data/spec/rubyspec/core/enumerable/sort_by_spec.rb +31 -0
- data/spec/rubyspec/core/hash/size_spec.rb +1 -1
- data/spec/rubyspec/core/hash/to_native_spec.rb +3 -3
- data/spec/rubyspec/core/string/fixtures/classes.rb +49 -0
- data/spec/rubyspec/core/string/index_spec.rb +405 -0
- data/spec/rubyspec/filters/bugs/language/class.rb +0 -2
- data/spec/rubyspec/filters/bugs/language/module.rb +3 -0
- data/spec/rubyspec/language/array_spec.rb +1 -1
- data/spec/rubyspec/language/block_spec.rb +1 -1
- data/spec/rubyspec/language/module_spec.rb +5 -5
- data/spec/rubyspec/language/predefined_spec.rb +1 -2
- data/spec/rubyspec/library/stringscanner/element_reference_spec.rb +29 -0
- data/spec/rubyspec/spec_helper.rb +31 -0
- metadata +130 -76
- data/lib/opal/erb.rb +0 -41
- data/opal/erb.rb +0 -19
- data/spec/opal/erb/erb_spec.rb +0 -31
- data/spec/simple_erb_template.opalerb +0 -1
- data/spec/templates/foo/bar.opalerb +0 -1
- data/spec/templates/prefixed.opalerb +0 -1
data/lib/opal/lexer.rb
CHANGED
|
@@ -487,6 +487,9 @@ module Opal
|
|
|
487
487
|
if [:expr_beg, :expr_mid, :expr_class].include? @lex_state
|
|
488
488
|
@lex_state = :expr_beg
|
|
489
489
|
return '::@', scanner.matched
|
|
490
|
+
elsif space_seen && @lex_state == :expr_arg
|
|
491
|
+
@lex_state = :expr_beg
|
|
492
|
+
return '::@', scanner.matched
|
|
490
493
|
end
|
|
491
494
|
|
|
492
495
|
@lex_state = :expr_dot
|
|
@@ -665,8 +668,7 @@ module Opal
|
|
|
665
668
|
return [result, result]
|
|
666
669
|
|
|
667
670
|
elsif scanner.scan(/\?/)
|
|
668
|
-
|
|
669
|
-
if [:expr_end, :expr_endarg, :expr_arg].include?(@lex_state)
|
|
671
|
+
if [:expr_end, :expr_endarg].include?(@lex_state)
|
|
670
672
|
@lex_state = :expr_beg
|
|
671
673
|
return '?', scanner.matched
|
|
672
674
|
end
|
data/lib/opal/parser.rb
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
require 'opal/lexer'
|
|
2
2
|
require 'opal/grammar'
|
|
3
3
|
require 'opal/target_scope'
|
|
4
|
+
require 'opal/version'
|
|
4
5
|
|
|
5
6
|
module Opal
|
|
6
7
|
class Parser
|
|
7
8
|
|
|
9
|
+
class Fragment
|
|
10
|
+
|
|
11
|
+
attr_reader :code
|
|
12
|
+
|
|
13
|
+
def initialize(code, sexp = nil)
|
|
14
|
+
@code = code
|
|
15
|
+
@sexp = sexp
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_code
|
|
19
|
+
if @sexp
|
|
20
|
+
"/*:#{@sexp.line}*/#{@code}"
|
|
21
|
+
else
|
|
22
|
+
@code
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def inspect
|
|
27
|
+
"fragment(#{@code.inspect})"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
8
31
|
# Generated code gets indented with two spaces on each scope
|
|
9
32
|
INDENT = ' '
|
|
10
33
|
|
|
@@ -28,15 +51,10 @@ module Opal
|
|
|
28
51
|
# Statements which should not have ';' added to them.
|
|
29
52
|
STATEMENTS = [:xstr, :dxstr]
|
|
30
53
|
|
|
31
|
-
# Holds an array of paths which this file "requires".
|
|
32
|
-
# @return [Array<String>]
|
|
33
|
-
attr_reader :requires
|
|
34
|
-
|
|
35
54
|
attr_reader :result
|
|
36
55
|
|
|
37
56
|
def parse(source, options = {})
|
|
38
57
|
@sexp = Grammar.new.parse(source, options[:file])
|
|
39
|
-
@requires = []
|
|
40
58
|
@line = 1
|
|
41
59
|
@indent = ''
|
|
42
60
|
@unique = 0
|
|
@@ -47,14 +65,32 @@ module Opal
|
|
|
47
65
|
}
|
|
48
66
|
|
|
49
67
|
# options
|
|
50
|
-
@file
|
|
51
|
-
@
|
|
52
|
-
@
|
|
53
|
-
@
|
|
54
|
-
@
|
|
55
|
-
@
|
|
68
|
+
@file = options[:file] || '(file)'
|
|
69
|
+
@source_file = options[:source_file] || @file
|
|
70
|
+
@method_missing = (options[:method_missing] != false)
|
|
71
|
+
@optimized_operators = (options[:optimized_operators] != false)
|
|
72
|
+
@arity_check = options[:arity_check]
|
|
73
|
+
@const_missing = (options[:const_missing] != false)
|
|
74
|
+
@irb_vars = (options[:irb] == true)
|
|
75
|
+
@source_map = (options[:source_map_enabled] != false)
|
|
76
|
+
|
|
77
|
+
fragments = self.top(@sexp).flatten
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
code = @source_map ? fragments.map(&:to_code).join('') : fragments.map(&:code).join('')
|
|
80
|
+
|
|
81
|
+
@result = source_map_comment + version_comment + file_comment + code
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def version_comment
|
|
85
|
+
"/* Generated by Opal #{Opal::VERSION} */\n"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def source_map_comment
|
|
89
|
+
@source_map ? "//@ sourceMappingURL=/__opal_source_maps__/#{@file}.js.map\n" : ''
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def file_comment
|
|
93
|
+
@source_map ? "/*-file:#{@source_file}-*/" : ''
|
|
58
94
|
end
|
|
59
95
|
|
|
60
96
|
# This is called when a parsing/processing error occurs. This
|
|
@@ -101,6 +137,12 @@ module Opal
|
|
|
101
137
|
sexp
|
|
102
138
|
end
|
|
103
139
|
|
|
140
|
+
# @param [String] code the string of code
|
|
141
|
+
# @return [Fragment]
|
|
142
|
+
def fragment(code, sexp = nil)
|
|
143
|
+
Fragment.new(code, sexp)
|
|
144
|
+
end
|
|
145
|
+
|
|
104
146
|
# Converts a ruby method name into its javascript equivalent for
|
|
105
147
|
# a method/function call. All ruby method names get prefixed with
|
|
106
148
|
# a '$', and if the name is a valid javascript identifier, it will
|
|
@@ -138,24 +180,35 @@ module Opal
|
|
|
138
180
|
# @param [Array] sexp the sexp to process
|
|
139
181
|
# @return [String]
|
|
140
182
|
def top(sexp, options = {})
|
|
141
|
-
code = nil
|
|
183
|
+
code, vars = nil, nil
|
|
184
|
+
|
|
185
|
+
# empty file = nil as our top sexp
|
|
186
|
+
sexp = s(:nil) unless sexp
|
|
142
187
|
|
|
143
188
|
in_scope(:top) do
|
|
144
189
|
indent {
|
|
145
|
-
|
|
190
|
+
scope = s(:scope, sexp)
|
|
191
|
+
scope.line = sexp.line
|
|
192
|
+
|
|
193
|
+
code = process(scope, :stmt)
|
|
194
|
+
code.unshift fragment(@indent, sexp)
|
|
146
195
|
}
|
|
147
196
|
|
|
148
197
|
@scope.add_temp "self = __opal.top"
|
|
149
198
|
@scope.add_temp "__scope = __opal"
|
|
150
|
-
@scope.add_temp "nil = __opal.nil"
|
|
151
199
|
@scope.add_temp "$mm = __opal.mm"
|
|
152
|
-
@scope.add_temp "
|
|
200
|
+
@scope.add_temp "nil = __opal.nil"
|
|
201
|
+
@scope.add_temp "def = #{current_self}.constructor.prototype" if @scope.defines_defn
|
|
153
202
|
@helpers.keys.each { |h| @scope.add_temp "__#{h} = __opal.#{h}" }
|
|
154
203
|
|
|
155
|
-
|
|
204
|
+
vars = [fragment(INDENT, sexp), @scope.to_vars, fragment("\n", sexp)]
|
|
205
|
+
|
|
206
|
+
if @irb_vars
|
|
207
|
+
code.unshift fragment("if (!Opal.irb_vars) { Opal.irb_vars = {}; }\n", sexp)
|
|
208
|
+
end
|
|
156
209
|
end
|
|
157
210
|
|
|
158
|
-
"(function(__opal) {\n
|
|
211
|
+
[fragment("(function(__opal) {\n", sexp), vars, code, fragment("\n})(Opal);\n", sexp)]
|
|
159
212
|
end
|
|
160
213
|
|
|
161
214
|
# Every time the parser enters a new scope, this is called with
|
|
@@ -271,7 +324,7 @@ module Opal
|
|
|
271
324
|
|
|
272
325
|
@line = sexp.line
|
|
273
326
|
|
|
274
|
-
__send__
|
|
327
|
+
__send__(meth, sexp, level)
|
|
275
328
|
end
|
|
276
329
|
|
|
277
330
|
# The last sexps in method bodies, for example, need to be returned
|
|
@@ -371,21 +424,30 @@ module Opal
|
|
|
371
424
|
result = []
|
|
372
425
|
sexp << s(:nil) if sexp.empty?
|
|
373
426
|
|
|
427
|
+
join = (@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
|
|
428
|
+
|
|
374
429
|
until sexp.empty?
|
|
375
430
|
stmt = sexp.shift
|
|
376
|
-
|
|
431
|
+
|
|
432
|
+
result << fragment(join, sexp) unless result.empty?
|
|
377
433
|
|
|
378
434
|
# find any inline yield statements
|
|
379
435
|
if yasgn = find_inline_yield(stmt)
|
|
380
|
-
result <<
|
|
436
|
+
result << process(yasgn, level)
|
|
437
|
+
result << fragment(";", yasgn)
|
|
381
438
|
end
|
|
382
439
|
|
|
383
440
|
expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
|
|
441
|
+
|
|
384
442
|
code = process(stmt, level)
|
|
385
|
-
|
|
443
|
+
|
|
444
|
+
result << code
|
|
445
|
+
if expr
|
|
446
|
+
result << fragment(";", stmt)
|
|
447
|
+
end
|
|
386
448
|
end
|
|
387
449
|
|
|
388
|
-
result
|
|
450
|
+
result
|
|
389
451
|
end
|
|
390
452
|
|
|
391
453
|
# When a block sexp gets generated, any inline yields (i.e. yield
|
|
@@ -440,28 +502,30 @@ module Opal
|
|
|
440
502
|
def process_scope(sexp, level)
|
|
441
503
|
stmt = sexp.shift
|
|
442
504
|
if stmt
|
|
443
|
-
|
|
444
|
-
|
|
505
|
+
unless @scope.class_scope?
|
|
506
|
+
stmt = returns stmt
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
process stmt, :stmt
|
|
445
510
|
else
|
|
446
|
-
|
|
511
|
+
fragment("nil", sexp)
|
|
447
512
|
end
|
|
448
|
-
|
|
449
|
-
code
|
|
450
513
|
end
|
|
451
514
|
|
|
452
515
|
# s(:js_return, sexp)
|
|
453
516
|
def process_js_return(sexp, level)
|
|
454
|
-
"return
|
|
517
|
+
[fragment("return ", sexp), process(sexp.shift, :expr)]
|
|
455
518
|
end
|
|
456
519
|
|
|
457
520
|
# s(:js_tmp, str)
|
|
458
521
|
def process_js_tmp(sexp, level)
|
|
459
|
-
sexp.shift.to_s
|
|
522
|
+
fragment(sexp.shift.to_s, sexp)
|
|
460
523
|
end
|
|
461
524
|
|
|
462
525
|
def process_operator(sexp, level)
|
|
463
526
|
meth, recv, arg = sexp
|
|
464
527
|
mid = mid_to_jsid meth.to_s
|
|
528
|
+
result = []
|
|
465
529
|
|
|
466
530
|
if @optimized_operators
|
|
467
531
|
with_temp do |a|
|
|
@@ -469,21 +533,27 @@ module Opal
|
|
|
469
533
|
l = process recv, :expr
|
|
470
534
|
r = process arg, :expr
|
|
471
535
|
|
|
472
|
-
"(
|
|
473
|
-
|
|
536
|
+
result << fragment("(#{a} = ", sexp)
|
|
537
|
+
result << l
|
|
538
|
+
result << fragment(", #{b} = ", sexp)
|
|
539
|
+
result << r
|
|
540
|
+
result << fragment(", typeof(#{a}) === 'number' ? #{a} #{meth} #{b} ", sexp)
|
|
541
|
+
result << fragment(": #{a}#{mid}(#{b}))", sexp)
|
|
474
542
|
end
|
|
475
543
|
end
|
|
476
544
|
else
|
|
477
545
|
"#{process recv, :recv}#{mid}(#{process arg, :expr})"
|
|
478
546
|
end
|
|
547
|
+
|
|
548
|
+
result
|
|
479
549
|
end
|
|
480
550
|
|
|
481
551
|
def js_block_given(sexp, level)
|
|
482
552
|
@scope.uses_block!
|
|
483
553
|
if @scope.block_name
|
|
484
|
-
"(#{@scope.block_name} !== nil)"
|
|
554
|
+
fragment("(#{@scope.block_name} !== nil)", sexp)
|
|
485
555
|
else
|
|
486
|
-
"false"
|
|
556
|
+
fragment("false", sexp)
|
|
487
557
|
end
|
|
488
558
|
end
|
|
489
559
|
|
|
@@ -491,7 +561,7 @@ module Opal
|
|
|
491
561
|
@scope.uses_block!
|
|
492
562
|
name = @scope.block_name
|
|
493
563
|
|
|
494
|
-
reverse ? "#{ name } === nil" : "#{ name } !== nil"
|
|
564
|
+
fragment((reverse ? "#{ name } === nil" : "#{ name } !== nil"), sexp)
|
|
495
565
|
end
|
|
496
566
|
|
|
497
567
|
# s(:lit, 1)
|
|
@@ -500,11 +570,15 @@ module Opal
|
|
|
500
570
|
val = sexp.shift
|
|
501
571
|
case val
|
|
502
572
|
when Numeric
|
|
503
|
-
level == :recv
|
|
573
|
+
if level == :recv
|
|
574
|
+
fragment("(#{val.inspect})", sexp)
|
|
575
|
+
else
|
|
576
|
+
fragment(val.inspect, sexp)
|
|
577
|
+
end
|
|
504
578
|
when Symbol
|
|
505
|
-
val.to_s.inspect
|
|
579
|
+
fragment(val.to_s.inspect, sexp)
|
|
506
580
|
when Regexp
|
|
507
|
-
val == // ? /^/.inspect : val.inspect
|
|
581
|
+
fragment((val == // ? /^/.inspect : val.inspect), sexp)
|
|
508
582
|
when Range
|
|
509
583
|
@helpers[:range] = true
|
|
510
584
|
"__range(#{val.begin}, #{val.end}, #{val.exclude_end?})"
|
|
@@ -514,31 +588,37 @@ module Opal
|
|
|
514
588
|
end
|
|
515
589
|
|
|
516
590
|
def process_dregx(sexp, level)
|
|
517
|
-
|
|
591
|
+
result = []
|
|
592
|
+
|
|
593
|
+
sexp.each do |part|
|
|
594
|
+
result << fragment(" + ", sexp) unless result.empty?
|
|
595
|
+
|
|
518
596
|
if String === part
|
|
519
|
-
part.inspect
|
|
597
|
+
result << fragment(part.inspect, sexp)
|
|
520
598
|
elsif part[0] == :str
|
|
521
|
-
process
|
|
599
|
+
result << process(part, :expr)
|
|
522
600
|
else
|
|
523
|
-
process
|
|
601
|
+
result << process(part[1], :expr)
|
|
524
602
|
end
|
|
525
603
|
end
|
|
526
604
|
|
|
527
|
-
"(new RegExp(
|
|
605
|
+
[fragment("(new RegExp(", sexp), result, fragment("))", sexp)]
|
|
528
606
|
end
|
|
529
607
|
|
|
530
608
|
def process_dot2(sexp, level)
|
|
531
609
|
lhs = process sexp[0], :expr
|
|
532
610
|
rhs = process sexp[1], :expr
|
|
533
611
|
@helpers[:range] = true
|
|
534
|
-
|
|
612
|
+
|
|
613
|
+
[fragment("__range(", sexp), lhs, fragment(", ", sexp), rhs, fragment(", false)", sexp)]
|
|
535
614
|
end
|
|
536
615
|
|
|
537
616
|
def process_dot3(sexp, level)
|
|
538
617
|
lhs = process sexp[0], :expr
|
|
539
618
|
rhs = process sexp[1], :expr
|
|
540
619
|
@helpers[:range] = true
|
|
541
|
-
|
|
620
|
+
|
|
621
|
+
[fragment("__range(", sexp), lhs, fragment(", ", sexp), rhs, fragment(", true)", sexp)]
|
|
542
622
|
end
|
|
543
623
|
|
|
544
624
|
# s(:str, "string")
|
|
@@ -546,9 +626,9 @@ module Opal
|
|
|
546
626
|
str = sexp.shift
|
|
547
627
|
if str == @file
|
|
548
628
|
@uses_file = true
|
|
549
|
-
@file.inspect
|
|
629
|
+
fragment(@file.inspect, sexp)
|
|
550
630
|
else
|
|
551
|
-
str.inspect
|
|
631
|
+
fragment(str.inspect, sexp)
|
|
552
632
|
end
|
|
553
633
|
end
|
|
554
634
|
|
|
@@ -556,28 +636,30 @@ module Opal
|
|
|
556
636
|
part = sexp[0]
|
|
557
637
|
case part[0]
|
|
558
638
|
when :self
|
|
559
|
-
"self".inspect
|
|
639
|
+
fragment("self".inspect, sexp)
|
|
560
640
|
when :nil
|
|
561
|
-
"nil".inspect
|
|
641
|
+
fragment("nil".inspect, sexp)
|
|
562
642
|
when :true
|
|
563
|
-
"true".inspect
|
|
643
|
+
fragment("true".inspect, sexp)
|
|
564
644
|
when :false
|
|
565
|
-
"false".inspect
|
|
645
|
+
fragment("false".inspect, sexp)
|
|
566
646
|
when :call
|
|
567
647
|
mid = mid_to_jsid part[2].to_s
|
|
568
|
-
recv = part[1] ? process(part[1], :expr) : current_self
|
|
569
|
-
"(
|
|
648
|
+
recv = part[1] ? process(part[1], :expr) : fragment(current_self, sexp)
|
|
649
|
+
[fragment("(", sexp), recv, fragment("#{mid} ? 'method' : nil)", sexp)]
|
|
570
650
|
when :xstr
|
|
571
|
-
"(typeof(
|
|
651
|
+
[fragment("(typeof(", sexp), process(part, :expr), fragment(") !== 'undefined')", sexp)]
|
|
572
652
|
when :const
|
|
573
|
-
"(__scope.#{part[1].to_s} != null)"
|
|
653
|
+
fragment("(__scope.#{part[1].to_s} != null)", sexp)
|
|
574
654
|
when :colon2
|
|
575
|
-
"false"
|
|
655
|
+
fragment("false", sexp)
|
|
576
656
|
when :ivar
|
|
577
657
|
ivar_name = part[1].to_s[1..-1]
|
|
578
658
|
with_temp do |t|
|
|
579
|
-
"((#{t} = #{current_self}[#{ivar_name.inspect}], #{t} != null && #{t} !== nil) ? 'instance-variable' : nil)"
|
|
659
|
+
fragment("((#{t} = #{current_self}[#{ivar_name.inspect}], #{t} != null && #{t} !== nil) ? 'instance-variable' : nil)", sexp)
|
|
580
660
|
end
|
|
661
|
+
when :lvar
|
|
662
|
+
fragment("local-variable", sexp)
|
|
581
663
|
else
|
|
582
664
|
raise "bad defined? part: #{part[0]}"
|
|
583
665
|
end
|
|
@@ -586,7 +668,8 @@ module Opal
|
|
|
586
668
|
# s(:not, sexp)
|
|
587
669
|
def process_not(sexp, level)
|
|
588
670
|
with_temp do |tmp|
|
|
589
|
-
|
|
671
|
+
expr = sexp.shift
|
|
672
|
+
[fragment("(#{tmp} = ", sexp), process(expr, :expr), fragment(", (#{tmp} === nil || #{tmp} === false))", sexp)]
|
|
590
673
|
end
|
|
591
674
|
end
|
|
592
675
|
|
|
@@ -600,10 +683,11 @@ module Opal
|
|
|
600
683
|
|
|
601
684
|
body ||= s(:nil)
|
|
602
685
|
body = returns body
|
|
603
|
-
code =
|
|
686
|
+
code = []
|
|
604
687
|
params = nil
|
|
605
688
|
scope_name = nil
|
|
606
689
|
identity = nil
|
|
690
|
+
to_vars = nil
|
|
607
691
|
|
|
608
692
|
args = nil if Fixnum === args # argh
|
|
609
693
|
args ||= s(:masgn, s(:array))
|
|
@@ -623,20 +707,20 @@ module Opal
|
|
|
623
707
|
indent do
|
|
624
708
|
in_scope(:iter) do
|
|
625
709
|
identity = @scope.identify!
|
|
626
|
-
@scope.add_temp "
|
|
710
|
+
@scope.add_temp "#{current_self} = #{identity}._s || this"
|
|
627
711
|
|
|
628
712
|
args[1..-1].each do |arg|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
code
|
|
713
|
+
arg = arg[1]
|
|
714
|
+
arg = "#{arg}$" if RESERVED.include? arg.to_s
|
|
715
|
+
code << fragment("if (#{arg} == null) #{arg} = nil;\n", sexp)
|
|
632
716
|
end
|
|
633
717
|
|
|
634
718
|
params = js_block_args(args[1..-1])
|
|
635
|
-
# params.unshift '_$'
|
|
636
719
|
|
|
637
720
|
if splat
|
|
721
|
+
@scope.add_arg splat
|
|
638
722
|
params << splat
|
|
639
|
-
code
|
|
723
|
+
code << fragment("#{splat} = __slice.call(arguments, #{len - 1});", sexp)
|
|
640
724
|
end
|
|
641
725
|
|
|
642
726
|
if block_arg
|
|
@@ -644,25 +728,30 @@ module Opal
|
|
|
644
728
|
@scope.add_temp block_arg
|
|
645
729
|
@scope.add_temp '__context'
|
|
646
730
|
scope_name = @scope.identify!
|
|
647
|
-
blk = "\n%s%s = %s._p || nil, __context = %s._s, %s.p = null;\n%s" %
|
|
648
|
-
[@indent, block_arg, scope_name, block_arg, scope_name, @indent]
|
|
649
731
|
|
|
650
|
-
|
|
732
|
+
blk = []
|
|
733
|
+
blk << fragment("\n#@indent#{block_arg} = #{scope_name}._p || nil, #{scope_name}.p = null;\n#@indent", sexp)
|
|
734
|
+
|
|
735
|
+
code.unshift blk
|
|
651
736
|
end
|
|
652
737
|
|
|
653
|
-
code
|
|
738
|
+
code << fragment("\n#@indent", sexp)
|
|
739
|
+
code << process(body, :stmt)
|
|
654
740
|
|
|
655
741
|
if @scope.defines_defn
|
|
656
742
|
@scope.add_temp "def = ((typeof(#{current_self}) === 'function') ? #{current_self}.prototype : #{current_self})"
|
|
657
743
|
end
|
|
658
744
|
|
|
659
|
-
|
|
745
|
+
to_vars = [fragment("\n#@indent", sexp), @scope.to_vars, fragment("\n#@indent", sexp)]
|
|
660
746
|
end
|
|
661
747
|
end
|
|
662
748
|
|
|
663
|
-
itercode = "function(#{params.join ', '}) {\n
|
|
664
|
-
call << ("(%s = %s, %s._s = %s, %s)" % [identity, itercode, identity, current_self, identity])
|
|
749
|
+
itercode = [fragment("function(#{params.join ', '}) {\n", sexp), to_vars, code, fragment("\n#@indent}", sexp)]
|
|
665
750
|
|
|
751
|
+
itercode.unshift fragment("(#{identity} = ", sexp)
|
|
752
|
+
itercode << fragment(", #{identity}._s = #{current_self}, #{identity})", sexp)
|
|
753
|
+
|
|
754
|
+
call << itercode
|
|
666
755
|
process call, level
|
|
667
756
|
end
|
|
668
757
|
|
|
@@ -701,29 +790,22 @@ module Opal
|
|
|
701
790
|
attrs.each do |attr|
|
|
702
791
|
mid = attr[1]
|
|
703
792
|
ivar = "@#{mid}".to_sym
|
|
704
|
-
pre = @scope.proto
|
|
705
793
|
|
|
706
794
|
unless meth == :attr_writer
|
|
795
|
+
out << fragment(", \n#@indent") unless out.empty?
|
|
707
796
|
out << process(s(:defn, mid, s(:args), s(:scope, s(:ivar, ivar))), :stmt)
|
|
708
797
|
end
|
|
709
798
|
|
|
710
799
|
unless meth == :attr_reader
|
|
800
|
+
out << fragment(", \n#@indent") unless out.empty?
|
|
711
801
|
mid = "#{mid}=".to_sym
|
|
712
802
|
out << process(s(:defn, mid, s(:args, :val), s(:scope,
|
|
713
803
|
s(:iasgn, ivar, s(:lvar, :val)))), :stmt)
|
|
714
804
|
end
|
|
715
805
|
end
|
|
716
806
|
|
|
717
|
-
out
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
def handle_alias_native(sexp)
|
|
721
|
-
args = sexp[2]
|
|
722
|
-
meth = mid_to_jsid args[1][1].to_s
|
|
723
|
-
func = args[2][1]
|
|
724
|
-
|
|
725
|
-
@scope.methods << meth
|
|
726
|
-
"%s%s = %s.%s" % [@scope.proto, meth, @scope.proto, func]
|
|
807
|
+
out << fragment(", nil")
|
|
808
|
+
out
|
|
727
809
|
end
|
|
728
810
|
|
|
729
811
|
# s(:call, recv, :mid, s(:arglist))
|
|
@@ -732,21 +814,27 @@ module Opal
|
|
|
732
814
|
recv, meth, arglist, iter = sexp
|
|
733
815
|
mid = mid_to_jsid meth.to_s
|
|
734
816
|
|
|
817
|
+
# we are trying to access a lvar in irb mode
|
|
818
|
+
if @irb_vars and @scope.top? and arglist == s(:arglist) and recv == nil
|
|
819
|
+
return with_temp { |t|
|
|
820
|
+
lvar = meth.intern
|
|
821
|
+
lvar = "#{lvar}$" if RESERVED.include? lvar
|
|
822
|
+
call = s(:call, s(:self), meth.intern, s(:arglist))
|
|
823
|
+
[fragment("((#{t} = Opal.irb_vars.#{lvar}) == null ? ", sexp), process(call, :expr), fragment(" : #{t})", sexp)]
|
|
824
|
+
}
|
|
825
|
+
end
|
|
826
|
+
|
|
735
827
|
case meth
|
|
736
828
|
when :attr_reader, :attr_writer, :attr_accessor
|
|
737
829
|
return handle_attr_optimize(meth, arglist[1..-1]) if @scope.class_scope?
|
|
738
830
|
when :block_given?
|
|
739
831
|
return js_block_given(sexp, level)
|
|
740
|
-
when :alias_native
|
|
741
|
-
return handle_alias_native(sexp) if @scope.class_scope?
|
|
742
|
-
when :require
|
|
743
|
-
return handle_require arglist[1]
|
|
744
832
|
end
|
|
745
833
|
|
|
746
834
|
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
|
747
835
|
|
|
748
836
|
if Array === arglist.last and arglist.last.first == :block_pass
|
|
749
|
-
block = process
|
|
837
|
+
block = process(arglist.pop, :expr)
|
|
750
838
|
elsif iter
|
|
751
839
|
block = iter
|
|
752
840
|
end
|
|
@@ -767,17 +855,29 @@ module Opal
|
|
|
767
855
|
arglist.insert 1, call_recv unless splat
|
|
768
856
|
args = process arglist, :expr
|
|
769
857
|
|
|
770
|
-
dispatch = "((#{tmprecv} = #{recv_code})#{mid} || $mm('#{
|
|
858
|
+
dispatch = "((#{tmprecv} = #{recv_code})#{mid} || $mm('#{meth.to_s}'))"
|
|
859
|
+
dispatch = [fragment("((#{tmprecv} = ", sexp), recv_code, fragment(")#{mid} || $mm('#{meth.to_s}'))", sexp)]
|
|
771
860
|
|
|
772
861
|
if tmpfunc
|
|
773
|
-
dispatch
|
|
862
|
+
dispatch.unshift fragment("(#{tmpfunc} = ", sexp)
|
|
863
|
+
dispatch << fragment(", #{tmpfunc}._p = ", sexp)
|
|
864
|
+
dispatch << block
|
|
865
|
+
dispatch << fragment(", #{tmpfunc})", sexp)
|
|
774
866
|
end
|
|
775
867
|
|
|
776
|
-
|
|
777
|
-
"
|
|
868
|
+
if splat
|
|
869
|
+
dispatch << fragment(".apply(", sexp)
|
|
870
|
+
dispatch << process(call_recv, :expr)
|
|
871
|
+
dispatch << fragment(", ", sexp)
|
|
872
|
+
dispatch << args
|
|
873
|
+
dispatch << fragment(")", sexp)
|
|
778
874
|
else
|
|
779
|
-
"
|
|
875
|
+
dispatch << fragment(".call(", sexp)
|
|
876
|
+
dispatch.push(*args)
|
|
877
|
+
dispatch << fragment(")", sexp)
|
|
780
878
|
end
|
|
879
|
+
|
|
880
|
+
result = dispatch
|
|
781
881
|
else
|
|
782
882
|
args = process arglist, :expr
|
|
783
883
|
dispatch = tmprecv ? "(#{tmprecv} = #{recv_code})#{mid}" : "#{recv_code}#{mid}"
|
|
@@ -788,86 +888,50 @@ module Opal
|
|
|
788
888
|
result
|
|
789
889
|
end
|
|
790
890
|
|
|
791
|
-
def handle_require(sexp)
|
|
792
|
-
str = handle_require_sexp sexp
|
|
793
|
-
@requires << str unless str.nil?
|
|
794
|
-
""
|
|
795
|
-
end
|
|
796
|
-
|
|
797
|
-
def handle_require_sexp(sexp)
|
|
798
|
-
type = sexp.shift
|
|
799
|
-
|
|
800
|
-
if type == :str
|
|
801
|
-
return sexp[0]
|
|
802
|
-
elsif type == :call
|
|
803
|
-
recv, meth, args = sexp
|
|
804
|
-
parts = args[1..-1].map { |s| handle_require_sexp s }
|
|
805
|
-
|
|
806
|
-
if recv == [:const, :File]
|
|
807
|
-
if meth == :expand_path
|
|
808
|
-
return handle_expand_path(*parts)
|
|
809
|
-
elsif meth == :join
|
|
810
|
-
return handle_expand_path parts.join("/")
|
|
811
|
-
elsif meth == :dirname
|
|
812
|
-
return handle_expand_path parts[0].split("/")[0...-1].join("/")
|
|
813
|
-
end
|
|
814
|
-
end
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
case @dynamic_require_severity
|
|
819
|
-
when :error
|
|
820
|
-
error "Cannot handle dynamic require"
|
|
821
|
-
when :warning
|
|
822
|
-
warning "Cannot handle dynamic require"
|
|
823
|
-
end
|
|
824
|
-
end
|
|
825
|
-
|
|
826
|
-
def handle_expand_path(path, base = '')
|
|
827
|
-
"#{base}/#{path}".split("/").inject([]) do |path, part|
|
|
828
|
-
if part == ''
|
|
829
|
-
# we had '//', so ignore
|
|
830
|
-
elsif part == '..'
|
|
831
|
-
path.pop
|
|
832
|
-
else
|
|
833
|
-
path << part
|
|
834
|
-
end
|
|
835
|
-
|
|
836
|
-
path
|
|
837
|
-
end.join "/"
|
|
838
|
-
end
|
|
839
|
-
|
|
840
891
|
# s(:arglist, [arg [, arg ..]])
|
|
841
892
|
def process_arglist(sexp, level)
|
|
842
|
-
code =
|
|
893
|
+
code = []
|
|
843
894
|
work = []
|
|
844
895
|
|
|
845
896
|
until sexp.empty?
|
|
846
|
-
|
|
847
|
-
|
|
897
|
+
current = sexp.shift
|
|
898
|
+
splat = current.first == :splat
|
|
899
|
+
arg = process current, :expr
|
|
848
900
|
|
|
849
901
|
if splat
|
|
850
902
|
if work.empty?
|
|
851
903
|
if code.empty?
|
|
852
|
-
code
|
|
904
|
+
code << fragment("[].concat(", sexp)
|
|
905
|
+
code << arg
|
|
906
|
+
code << fragment(")", sexp)
|
|
853
907
|
else
|
|
854
908
|
code += ".concat(#{arg})"
|
|
855
909
|
end
|
|
856
910
|
else
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
911
|
+
if code.empty?
|
|
912
|
+
code << [fragment("[", sexp), work, fragment("]", sexp)]
|
|
913
|
+
else
|
|
914
|
+
code << [fragment(".concat([", sexp), work, fragment("])", sexp)]
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
code << [fragment(".concat(", sexp), arg, fragment(")", sexp)]
|
|
860
918
|
end
|
|
861
919
|
|
|
862
920
|
work = []
|
|
863
921
|
else
|
|
864
|
-
work.
|
|
922
|
+
work << fragment(", ", current) unless work.empty?
|
|
923
|
+
work.push(*arg)
|
|
865
924
|
end
|
|
866
925
|
end
|
|
867
926
|
|
|
868
927
|
unless work.empty?
|
|
869
|
-
join
|
|
870
|
-
|
|
928
|
+
join = work
|
|
929
|
+
|
|
930
|
+
if code.empty?
|
|
931
|
+
code = join
|
|
932
|
+
else
|
|
933
|
+
code << fragment(".concat(", sexp) << join << fragment(")", sexp)
|
|
934
|
+
end
|
|
871
935
|
end
|
|
872
936
|
|
|
873
937
|
code
|
|
@@ -875,9 +939,13 @@ module Opal
|
|
|
875
939
|
|
|
876
940
|
# s(:splat, sexp)
|
|
877
941
|
def process_splat(sexp, level)
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
942
|
+
if sexp.first == [:nil]
|
|
943
|
+
[fragment("[]", sexp)]
|
|
944
|
+
elsif sexp.first.first == :lit
|
|
945
|
+
[fragment("[", sexp), process(sexp.first, :expr), fragment("]", sexp)]
|
|
946
|
+
else
|
|
947
|
+
process sexp.first, :recv
|
|
948
|
+
end
|
|
881
949
|
end
|
|
882
950
|
|
|
883
951
|
# s(:class, cid, super, body)
|
|
@@ -886,23 +954,23 @@ module Opal
|
|
|
886
954
|
|
|
887
955
|
body[1] = s(:nil) unless body[1]
|
|
888
956
|
|
|
889
|
-
code =
|
|
957
|
+
code = []
|
|
890
958
|
@helpers[:klass] = true
|
|
891
959
|
|
|
892
960
|
if Symbol === cid or String === cid
|
|
893
|
-
base =
|
|
961
|
+
base = process(s(:self), :expr)
|
|
894
962
|
name = cid.to_s
|
|
895
963
|
elsif cid[0] == :colon2
|
|
896
964
|
base = process(cid[1], :expr)
|
|
897
965
|
name = cid[2].to_s
|
|
898
966
|
elsif cid[0] == :colon3
|
|
899
|
-
base = 'Opal.Object'
|
|
967
|
+
base = process(s(:js_tmp, 'Opal.Object'), :expr)
|
|
900
968
|
name = cid[1].to_s
|
|
901
969
|
else
|
|
902
970
|
raise "Bad receiver in class"
|
|
903
971
|
end
|
|
904
972
|
|
|
905
|
-
sup = sup ? process(sup, :expr) : 'null'
|
|
973
|
+
sup = sup ? process(sup, :expr) : process(s(:js_tmp, 'null'), :expr)
|
|
906
974
|
|
|
907
975
|
indent do
|
|
908
976
|
in_scope(:class) do
|
|
@@ -925,8 +993,13 @@ module Opal
|
|
|
925
993
|
|
|
926
994
|
body = returns(body)
|
|
927
995
|
body = process body, :stmt
|
|
928
|
-
code
|
|
929
|
-
code
|
|
996
|
+
code << fragment("\n", sexp)
|
|
997
|
+
code << @scope.to_donate_methods
|
|
998
|
+
|
|
999
|
+
code << fragment(@indent, sexp)
|
|
1000
|
+
code << @scope.to_vars
|
|
1001
|
+
code << fragment("\n\n#@indent", sexp)
|
|
1002
|
+
code << body
|
|
930
1003
|
end
|
|
931
1004
|
end
|
|
932
1005
|
|
|
@@ -934,43 +1007,46 @@ module Opal
|
|
|
934
1007
|
cls = "function #{name}() {};"
|
|
935
1008
|
boot = "#{name} = __klass(__base, __super, #{name.inspect}, #{name});"
|
|
936
1009
|
|
|
937
|
-
"(function(__base, __super){#{spacer}#{cls}#{spacer}#{boot}\n
|
|
1010
|
+
[fragment("(function(__base, __super){#{spacer}#{cls}#{spacer}#{boot}\n", sexp),
|
|
1011
|
+
code, fragment("\n#@indent})", sexp), fragment("(", sexp), base, fragment(", ", sexp), sup, fragment(")", sexp)]
|
|
938
1012
|
end
|
|
939
1013
|
|
|
940
1014
|
# s(:sclass, recv, body)
|
|
941
1015
|
def process_sclass(sexp, level)
|
|
942
1016
|
recv = sexp[0]
|
|
943
1017
|
body = sexp[1]
|
|
944
|
-
code =
|
|
1018
|
+
code = []
|
|
945
1019
|
|
|
946
1020
|
in_scope(:sclass) do
|
|
947
1021
|
@scope.add_temp "__scope = #{current_self}._scope"
|
|
948
1022
|
@scope.add_temp "def = #{current_self}.prototype"
|
|
949
1023
|
|
|
950
1024
|
body = process body, :stmt
|
|
951
|
-
code
|
|
1025
|
+
code << @scope.to_vars << body
|
|
952
1026
|
end
|
|
953
1027
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1028
|
+
result = []
|
|
1029
|
+
result << fragment("(function(){", sexp) << code
|
|
1030
|
+
result << fragment("}).call(__opal.singleton(", sexp)
|
|
1031
|
+
result << process(recv, :expr) << fragment("))", sexp)
|
|
1032
|
+
result
|
|
957
1033
|
end
|
|
958
1034
|
|
|
959
1035
|
# s(:module, cid, body)
|
|
960
1036
|
def process_module(sexp, level)
|
|
961
1037
|
cid = sexp[0]
|
|
962
1038
|
body = sexp[1]
|
|
963
|
-
code =
|
|
1039
|
+
code = []
|
|
964
1040
|
@helpers[:module] = true
|
|
965
1041
|
|
|
966
1042
|
if Symbol === cid or String === cid
|
|
967
|
-
base =
|
|
1043
|
+
base = process(s(:self), :expr)
|
|
968
1044
|
name = cid.to_s
|
|
969
1045
|
elsif cid[0] == :colon2
|
|
970
1046
|
base = process(cid[1], :expr)
|
|
971
1047
|
name = cid[2].to_s
|
|
972
1048
|
elsif cid[0] == :colon3
|
|
973
|
-
base = 'Opal.Object'
|
|
1049
|
+
base = fragment('Opal.Object', sexp)
|
|
974
1050
|
name = cid[1].to_s
|
|
975
1051
|
else
|
|
976
1052
|
raise "Bad receiver in class"
|
|
@@ -981,7 +1057,13 @@ module Opal
|
|
|
981
1057
|
@scope.name = name
|
|
982
1058
|
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
|
|
983
1059
|
body = process body, :stmt
|
|
984
|
-
|
|
1060
|
+
|
|
1061
|
+
code << fragment(@indent, sexp)
|
|
1062
|
+
code.push(*@scope.to_vars)
|
|
1063
|
+
code << fragment("\n\n#@indent", sexp)
|
|
1064
|
+
code.push(*body)
|
|
1065
|
+
code << fragment("\n#@ident", sexp)
|
|
1066
|
+
code.push(*@scope.to_donate_methods)
|
|
985
1067
|
end
|
|
986
1068
|
end
|
|
987
1069
|
|
|
@@ -989,31 +1071,35 @@ module Opal
|
|
|
989
1071
|
cls = "function #{name}() {};"
|
|
990
1072
|
boot = "#{name} = __module(__base, #{name.inspect}, #{name});"
|
|
991
1073
|
|
|
992
|
-
"(function(__base){#{spacer}#{cls}#{spacer}#{boot}\n
|
|
993
|
-
|
|
1074
|
+
code.unshift fragment("(function(__base){#{spacer}#{cls}#{spacer}#{boot}\n", sexp)
|
|
1075
|
+
code << fragment("\n#@indent})(", sexp)
|
|
1076
|
+
code.push(*base)
|
|
1077
|
+
code << fragment(")", sexp)
|
|
994
1078
|
|
|
1079
|
+
code
|
|
1080
|
+
end
|
|
995
1081
|
|
|
996
1082
|
# undef :foo
|
|
997
1083
|
# => delete MyClass.prototype.$foo
|
|
998
1084
|
def process_undef(sexp, level)
|
|
999
|
-
"delete #{ @scope.proto }#{ mid_to_jsid sexp[0][1].to_s }"
|
|
1085
|
+
fragment("delete #{ @scope.proto }#{ mid_to_jsid sexp[0][1].to_s }", sexp)
|
|
1000
1086
|
end
|
|
1001
1087
|
|
|
1002
1088
|
# s(:defn, mid, s(:args), s(:scope))
|
|
1003
1089
|
def process_defn(sexp, level)
|
|
1004
1090
|
mid, args, stmts = sexp
|
|
1005
1091
|
|
|
1006
|
-
js_def nil, mid, args, stmts, sexp.line, sexp.end_line
|
|
1092
|
+
js_def nil, mid, args, stmts, sexp.line, sexp.end_line, sexp
|
|
1007
1093
|
end
|
|
1008
1094
|
|
|
1009
1095
|
# s(:defs, recv, mid, s(:args), s(:scope))
|
|
1010
1096
|
def process_defs(sexp, level)
|
|
1011
1097
|
recv, mid, args, stmts = sexp
|
|
1012
1098
|
|
|
1013
|
-
js_def recv, mid, args, stmts, sexp.line, sexp.end_line
|
|
1099
|
+
js_def recv, mid, args, stmts, sexp.line, sexp.end_line, sexp
|
|
1014
1100
|
end
|
|
1015
1101
|
|
|
1016
|
-
def js_def(recvr, mid, args, stmts, line, end_line)
|
|
1102
|
+
def js_def(recvr, mid, args, stmts, line, end_line, sexp)
|
|
1017
1103
|
jsid = mid_to_jsid mid.to_s
|
|
1018
1104
|
|
|
1019
1105
|
if recvr
|
|
@@ -1025,7 +1111,7 @@ module Opal
|
|
|
1025
1111
|
recv = current_self
|
|
1026
1112
|
end
|
|
1027
1113
|
|
|
1028
|
-
code =
|
|
1114
|
+
code = []
|
|
1029
1115
|
params = nil
|
|
1030
1116
|
scope_name = nil
|
|
1031
1117
|
uses_super = nil
|
|
@@ -1071,58 +1157,62 @@ module Opal
|
|
|
1071
1157
|
@scope.block_name = yielder
|
|
1072
1158
|
|
|
1073
1159
|
params = process args, :expr
|
|
1074
|
-
stmt_code = "\n#@indent"
|
|
1160
|
+
stmt_code = [fragment("\n#@indent", stmts), *process(stmts, :stmt)]
|
|
1075
1161
|
|
|
1076
1162
|
opt[1..-1].each do |o|
|
|
1077
1163
|
next if o[2][2] == :undefined
|
|
1078
|
-
|
|
1079
|
-
code
|
|
1080
|
-
|
|
1164
|
+
code << fragment("if (#{o[1]} == null) {\n#{@indent + INDENT}", o)
|
|
1165
|
+
code << process(o, :expr)
|
|
1166
|
+
code << fragment("\n#{@indent}}", o)
|
|
1081
1167
|
end if opt
|
|
1082
1168
|
|
|
1083
|
-
code
|
|
1169
|
+
code << fragment("#{splat} = __slice.call(arguments, #{argc});", sexp) if splat
|
|
1084
1170
|
|
|
1085
1171
|
scope_name = @scope.identity
|
|
1086
1172
|
|
|
1087
1173
|
if @scope.uses_block?
|
|
1088
1174
|
@scope.add_temp yielder
|
|
1089
|
-
blk = "\n%s%s = %s._p || nil, %s._p = null;\n%s" %
|
|
1175
|
+
blk = fragment(("\n%s%s = %s._p || nil, %s._p = null;\n%s" %
|
|
1176
|
+
[@indent, yielder, scope_name, scope_name, @indent]), sexp)
|
|
1090
1177
|
end
|
|
1091
1178
|
|
|
1092
|
-
code
|
|
1093
|
-
code
|
|
1179
|
+
code.push(*stmt_code)
|
|
1180
|
+
code.unshift blk if blk
|
|
1094
1181
|
|
|
1095
1182
|
uses_super = @scope.uses_super
|
|
1096
1183
|
|
|
1097
|
-
code = "#{arity_code}#@indent
|
|
1184
|
+
code = [fragment("#{arity_code}#@indent", sexp), @scope.to_vars, code]
|
|
1098
1185
|
end
|
|
1099
1186
|
end
|
|
1100
1187
|
|
|
1101
|
-
|
|
1188
|
+
result = [fragment("#{"#{scope_name} = " if scope_name}function(", sexp)]
|
|
1189
|
+
result.push(*params)
|
|
1190
|
+
result << fragment(") {\n", sexp)
|
|
1191
|
+
result.push(*code)
|
|
1192
|
+
result << fragment("\n#@indent}", sexp)
|
|
1102
1193
|
|
|
1103
1194
|
if recvr
|
|
1104
1195
|
if smethod
|
|
1105
|
-
"__opal.defs(#{@scope.name}, '$#{mid}',
|
|
1196
|
+
[fragment("__opal.defs(#{@scope.name}, '$#{mid}', ", sexp), result, fragment(")", sexp)]
|
|
1106
1197
|
else
|
|
1107
|
-
|
|
1198
|
+
[recv, fragment("#{jsid} = ", sexp), result]
|
|
1108
1199
|
end
|
|
1109
1200
|
elsif @scope.class? and @scope.name == 'Object'
|
|
1110
|
-
"#{current_self}._defn('$#{mid}',
|
|
1201
|
+
[fragment("#{current_self}._defn('$#{mid}', ", sexp), result, fragment(")", sexp)]
|
|
1111
1202
|
elsif @scope.class_scope?
|
|
1112
1203
|
@scope.methods << "$#{mid}"
|
|
1113
1204
|
if uses_super
|
|
1114
1205
|
@scope.add_temp uses_super
|
|
1115
1206
|
uses_super = "#{uses_super} = #{@scope.proto}#{jsid};\n#@indent"
|
|
1116
1207
|
end
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
# "#{ current_self }._defs('$#{mid}', #{defcode})"
|
|
1208
|
+
|
|
1209
|
+
[fragment("#{uses_super}#{@scope.proto}#{jsid} = ", sexp), result]
|
|
1120
1210
|
elsif @scope.type == :iter
|
|
1121
|
-
"def#{jsid} =
|
|
1211
|
+
[fragment("def#{jsid} = ", sexp), result]
|
|
1122
1212
|
elsif @scope.type == :top
|
|
1123
|
-
"#{ current_self }#{ jsid } =
|
|
1213
|
+
[fragment("#{ current_self }#{ jsid } = ", sexp), *result]
|
|
1124
1214
|
else
|
|
1125
|
-
"def#{jsid} =
|
|
1215
|
+
[fragment("def#{jsid} = ", sexp), result]
|
|
1126
1216
|
end
|
|
1127
1217
|
end
|
|
1128
1218
|
|
|
@@ -1157,12 +1247,12 @@ module Opal
|
|
|
1157
1247
|
args << a
|
|
1158
1248
|
end
|
|
1159
1249
|
|
|
1160
|
-
args.join ',
|
|
1250
|
+
[fragment(args.join(', '), exp)]
|
|
1161
1251
|
end
|
|
1162
1252
|
|
|
1163
1253
|
# s(:self) # => this
|
|
1164
1254
|
def process_self(sexp, level)
|
|
1165
|
-
current_self
|
|
1255
|
+
fragment(current_self, sexp)
|
|
1166
1256
|
end
|
|
1167
1257
|
|
|
1168
1258
|
# Returns the current value for 'self'. This will be native
|
|
@@ -1178,43 +1268,61 @@ module Opal
|
|
|
1178
1268
|
end
|
|
1179
1269
|
end
|
|
1180
1270
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1271
|
+
def process_true(sexp, level)
|
|
1272
|
+
fragment("true", sexp)
|
|
1273
|
+
end
|
|
1274
|
+
|
|
1275
|
+
def process_false(sexp, level)
|
|
1276
|
+
fragment("false", sexp)
|
|
1277
|
+
end
|
|
1278
|
+
|
|
1279
|
+
def process_nil(sexp, level)
|
|
1280
|
+
fragment("nil", sexp)
|
|
1188
1281
|
end
|
|
1189
1282
|
|
|
1190
1283
|
# s(:array [, sexp [, sexp]])
|
|
1191
1284
|
def process_array(sexp, level)
|
|
1192
|
-
return
|
|
1285
|
+
return [fragment("[]", sexp)] if sexp.empty?
|
|
1193
1286
|
|
|
1194
|
-
code =
|
|
1287
|
+
code = []
|
|
1195
1288
|
work = []
|
|
1196
1289
|
|
|
1197
1290
|
until sexp.empty?
|
|
1198
|
-
|
|
1199
|
-
|
|
1291
|
+
current = sexp.shift
|
|
1292
|
+
splat = current.first == :splat
|
|
1293
|
+
part = process current, :expr
|
|
1200
1294
|
|
|
1201
1295
|
if splat
|
|
1202
1296
|
if work.empty?
|
|
1203
|
-
|
|
1297
|
+
if code.empty?
|
|
1298
|
+
code << fragment("[].concat(", sexp) << part << fragment(")", sexp)
|
|
1299
|
+
else
|
|
1300
|
+
code << fragment(".concat(", sexp) << part << fragment(")", sexp)
|
|
1301
|
+
end
|
|
1204
1302
|
else
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1303
|
+
if code.empty?
|
|
1304
|
+
code << fragment("[", sexp) << work << fragment("]", sexp)
|
|
1305
|
+
else
|
|
1306
|
+
code << fragment(".concat([", sexp) << work << fragment("])", sexp)
|
|
1307
|
+
end
|
|
1308
|
+
|
|
1309
|
+
code << fragment(".concat(", sexp) << part << fragment(")", sexp)
|
|
1208
1310
|
end
|
|
1209
1311
|
work = []
|
|
1210
1312
|
else
|
|
1313
|
+
work << fragment(", ", current) unless work.empty?
|
|
1211
1314
|
work << part
|
|
1212
1315
|
end
|
|
1213
1316
|
end
|
|
1214
1317
|
|
|
1215
1318
|
unless work.empty?
|
|
1216
|
-
join
|
|
1217
|
-
|
|
1319
|
+
join = [fragment("[", sexp), work, fragment("]", sexp)]
|
|
1320
|
+
|
|
1321
|
+
if code.empty?
|
|
1322
|
+
code = join
|
|
1323
|
+
else
|
|
1324
|
+
code.push([fragment(".concat(", sexp), join, fragment(")", sexp)])
|
|
1325
|
+
end
|
|
1218
1326
|
end
|
|
1219
1327
|
|
|
1220
1328
|
code
|
|
@@ -1237,18 +1345,31 @@ module Opal
|
|
|
1237
1345
|
hash_obj = {}
|
|
1238
1346
|
hash_keys = []
|
|
1239
1347
|
keys.size.times do |i|
|
|
1240
|
-
k =
|
|
1348
|
+
k = keys[i][1].to_s.inspect
|
|
1241
1349
|
hash_keys << k unless hash_obj.include? k
|
|
1242
1350
|
hash_obj[k] = process(vals[i], :expr)
|
|
1243
1351
|
end
|
|
1244
1352
|
|
|
1245
|
-
|
|
1246
|
-
|
|
1353
|
+
result = []
|
|
1247
1354
|
@helpers[:hash2] = true
|
|
1248
|
-
|
|
1355
|
+
|
|
1356
|
+
hash_keys.each do |k|
|
|
1357
|
+
result << fragment(", ", sexp) unless result.empty?
|
|
1358
|
+
result << fragment("#{k}: ", sexp)
|
|
1359
|
+
result << hash_obj[k]
|
|
1360
|
+
end
|
|
1361
|
+
|
|
1362
|
+
[fragment("__hash2([#{hash_keys.join ', '}], {", sexp), result, fragment("})", sexp)]
|
|
1249
1363
|
else
|
|
1250
1364
|
@helpers[:hash] = true
|
|
1251
|
-
|
|
1365
|
+
result = []
|
|
1366
|
+
|
|
1367
|
+
sexp.each do |p|
|
|
1368
|
+
result << fragment(", ", p) unless result.empty?
|
|
1369
|
+
result << process(p, :expr)
|
|
1370
|
+
end
|
|
1371
|
+
|
|
1372
|
+
[fragment("__hash(", sexp), result, fragment(")", sexp)]
|
|
1252
1373
|
end
|
|
1253
1374
|
end
|
|
1254
1375
|
|
|
@@ -1256,14 +1377,16 @@ module Opal
|
|
|
1256
1377
|
def process_while(sexp, level)
|
|
1257
1378
|
expr, stmt = sexp
|
|
1258
1379
|
redo_var = @scope.new_temp
|
|
1380
|
+
code = []
|
|
1259
1381
|
|
|
1260
1382
|
stmt_level = if level == :expr or level == :recv
|
|
1261
1383
|
:stmt_closure
|
|
1262
1384
|
else
|
|
1263
1385
|
:stmt
|
|
1264
1386
|
end
|
|
1387
|
+
|
|
1388
|
+
code << js_truthy(expr) << fragment("){", sexp)
|
|
1265
1389
|
pre = "while ("
|
|
1266
|
-
code = "#{js_truthy expr}){"
|
|
1267
1390
|
|
|
1268
1391
|
in_while do
|
|
1269
1392
|
@while_loop[:closure] = true if stmt_level == :stmt_closure
|
|
@@ -1272,18 +1395,19 @@ module Opal
|
|
|
1272
1395
|
|
|
1273
1396
|
if @while_loop[:use_redo]
|
|
1274
1397
|
pre = "#{redo_var}=false;" + pre + "#{redo_var} || "
|
|
1275
|
-
code
|
|
1398
|
+
code << fragment("#{redo_var}=false;", sexp)
|
|
1276
1399
|
end
|
|
1277
1400
|
|
|
1278
|
-
code
|
|
1401
|
+
code << body
|
|
1279
1402
|
end
|
|
1280
1403
|
|
|
1281
|
-
code
|
|
1282
|
-
code
|
|
1404
|
+
code << fragment("}", sexp)
|
|
1405
|
+
code.unshift fragment(pre, sexp)
|
|
1283
1406
|
@scope.queue_temp redo_var
|
|
1284
1407
|
|
|
1285
1408
|
if stmt_level == :stmt_closure
|
|
1286
|
-
code
|
|
1409
|
+
code.unshift fragment("(function() {", sexp)
|
|
1410
|
+
code.push fragment("; return nil; }).call(#{current_self})", sexp)
|
|
1287
1411
|
end
|
|
1288
1412
|
|
|
1289
1413
|
code
|
|
@@ -1298,8 +1422,10 @@ module Opal
|
|
|
1298
1422
|
else
|
|
1299
1423
|
:stmt
|
|
1300
1424
|
end
|
|
1425
|
+
|
|
1426
|
+
code = []
|
|
1301
1427
|
pre = "while (!("
|
|
1302
|
-
code
|
|
1428
|
+
code << js_truthy(expr) << fragment(")) {", exp)
|
|
1303
1429
|
|
|
1304
1430
|
in_while do
|
|
1305
1431
|
@while_loop[:closure] = true if stmt_level == :stmt_closure
|
|
@@ -1308,18 +1434,19 @@ module Opal
|
|
|
1308
1434
|
|
|
1309
1435
|
if @while_loop[:use_redo]
|
|
1310
1436
|
pre = "#{redo_var}=false;" + pre + "#{redo_var} || "
|
|
1311
|
-
code
|
|
1437
|
+
code << fragment("#{redo_var}=false;", exp)
|
|
1312
1438
|
end
|
|
1313
1439
|
|
|
1314
|
-
code
|
|
1440
|
+
code << body
|
|
1315
1441
|
end
|
|
1316
1442
|
|
|
1317
|
-
code
|
|
1318
|
-
code
|
|
1443
|
+
code << fragment("}", exp)
|
|
1444
|
+
code.unshift fragment(pre, exp)
|
|
1319
1445
|
@scope.queue_temp redo_var
|
|
1320
1446
|
|
|
1321
1447
|
if stmt_level == :stmt_closure
|
|
1322
|
-
code
|
|
1448
|
+
code.unshift fragment("(function() {", exp)
|
|
1449
|
+
code << fragment("; return nil; }).call(#{current_self})", exp)
|
|
1323
1450
|
end
|
|
1324
1451
|
|
|
1325
1452
|
code
|
|
@@ -1334,10 +1461,10 @@ module Opal
|
|
|
1334
1461
|
|
|
1335
1462
|
if [:class, :module].include? @scope.type
|
|
1336
1463
|
@scope.methods << "$#{exp[0][1].to_s}"
|
|
1337
|
-
"%s%s = %s%s" % [@scope.proto, new, @scope.proto, old]
|
|
1464
|
+
fragment("%s%s = %s%s" % [@scope.proto, new, @scope.proto, old], exp)
|
|
1338
1465
|
else
|
|
1339
1466
|
current = current_self
|
|
1340
|
-
"%s.prototype%s = %s.prototype%s" % [current, new, current, old]
|
|
1467
|
+
fragment("%s.prototype%s = %s.prototype%s" % [current, new, current, old], exp)
|
|
1341
1468
|
end
|
|
1342
1469
|
end
|
|
1343
1470
|
|
|
@@ -1346,21 +1473,25 @@ module Opal
|
|
|
1346
1473
|
rhs = sexp[1]
|
|
1347
1474
|
tmp = @scope.new_temp
|
|
1348
1475
|
len = 0
|
|
1476
|
+
code = []
|
|
1349
1477
|
|
|
1350
1478
|
# remote :array part
|
|
1351
1479
|
lhs.shift
|
|
1352
1480
|
if rhs[0] == :array
|
|
1353
1481
|
len = rhs.length - 1 # we are guaranteed an array of this length
|
|
1354
|
-
code
|
|
1482
|
+
code << fragment("#{tmp} = ", sexp) << process(rhs, :expr)
|
|
1355
1483
|
elsif rhs[0] == :to_ary
|
|
1356
|
-
code
|
|
1484
|
+
code << fragment("((#{tmp} = ", sexp) << process(rhs[1], :expr)
|
|
1485
|
+
code << fragment(")._isArray ? #{tmp} : (#{tmp} = [#{tmp}]))", sexp)
|
|
1357
1486
|
elsif rhs[0] == :splat
|
|
1358
|
-
code
|
|
1487
|
+
code << fragment("(#{tmp} = ", sexp) << process(rhs[1], :expr)
|
|
1488
|
+
code << fragment(")['$to_a'] ? (#{tmp} = #{tmp}['$to_a']()) : (#{tmp})._isArray ? #{tmp} : (#{tmp} = [#{tmp}])", sexp)
|
|
1359
1489
|
else
|
|
1360
1490
|
raise "Unsupported mlhs type"
|
|
1361
1491
|
end
|
|
1362
1492
|
|
|
1363
1493
|
lhs.each_with_index do |l, idx|
|
|
1494
|
+
code << fragment(", ", sexp) unless code.empty?
|
|
1364
1495
|
|
|
1365
1496
|
if l.first == :splat
|
|
1366
1497
|
s = l[1]
|
|
@@ -1377,7 +1508,7 @@ module Opal
|
|
|
1377
1508
|
end
|
|
1378
1509
|
|
|
1379
1510
|
@scope.queue_temp tmp
|
|
1380
|
-
code
|
|
1511
|
+
code
|
|
1381
1512
|
end
|
|
1382
1513
|
|
|
1383
1514
|
def process_svalue(sexp, level)
|
|
@@ -1389,16 +1520,33 @@ module Opal
|
|
|
1389
1520
|
lvar = sexp[0]
|
|
1390
1521
|
rhs = sexp[1]
|
|
1391
1522
|
lvar = "#{lvar}$".to_sym if RESERVED.include? lvar.to_s
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1523
|
+
|
|
1524
|
+
if @irb_vars and @scope.top?
|
|
1525
|
+
[fragment("Opal.irb_vars.#{lvar} = ", sexp), process(rhs, :expr)]
|
|
1526
|
+
else
|
|
1527
|
+
@scope.add_local lvar
|
|
1528
|
+
rhs = process(rhs, :expr)
|
|
1529
|
+
result = [fragment(lvar, sexp), fragment(" = ", sexp), rhs]
|
|
1530
|
+
|
|
1531
|
+
if level == :recv
|
|
1532
|
+
result.unshift fragment("(", sexp)
|
|
1533
|
+
result.push fragment(")", sexp)
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
result
|
|
1537
|
+
end
|
|
1395
1538
|
end
|
|
1396
1539
|
|
|
1397
1540
|
# s(:lvar, :lvar)
|
|
1398
|
-
def process_lvar(
|
|
1399
|
-
lvar =
|
|
1541
|
+
def process_lvar(sexp, level)
|
|
1542
|
+
lvar = sexp.shift.to_s
|
|
1400
1543
|
lvar = "#{lvar}$" if RESERVED.include? lvar
|
|
1401
|
-
|
|
1544
|
+
|
|
1545
|
+
if @irb_vars and @scope.top?
|
|
1546
|
+
with_temp { |t| fragment("((#{t} = Opal.irb_vars.#{lvar}) == null ? nil : #{t})", sexp) }
|
|
1547
|
+
else
|
|
1548
|
+
fragment(lvar, sexp)
|
|
1549
|
+
end
|
|
1402
1550
|
end
|
|
1403
1551
|
|
|
1404
1552
|
# s(:iasgn, :ivar, rhs)
|
|
@@ -1407,7 +1555,7 @@ module Opal
|
|
|
1407
1555
|
rhs = exp[1]
|
|
1408
1556
|
ivar = ivar.to_s[1..-1]
|
|
1409
1557
|
lhs = RESERVED.include?(ivar) ? "#{current_self}['#{ivar}']" : "#{current_self}.#{ivar}"
|
|
1410
|
-
|
|
1558
|
+
[fragment(lhs, exp), fragment(" = ", exp), process(rhs, :expr)]
|
|
1411
1559
|
end
|
|
1412
1560
|
|
|
1413
1561
|
# s(:ivar, :ivar)
|
|
@@ -1415,18 +1563,18 @@ module Opal
|
|
|
1415
1563
|
ivar = exp.shift.to_s[1..-1]
|
|
1416
1564
|
part = RESERVED.include?(ivar) ? "['#{ivar}']" : ".#{ivar}"
|
|
1417
1565
|
@scope.add_ivar part
|
|
1418
|
-
"#{current_self}#{part}"
|
|
1566
|
+
fragment("#{current_self}#{part}", exp)
|
|
1419
1567
|
end
|
|
1420
1568
|
|
|
1421
1569
|
# s(:gvar, gvar)
|
|
1422
1570
|
def process_gvar(sexp, level)
|
|
1423
1571
|
gvar = sexp.shift.to_s[1..-1]
|
|
1424
1572
|
@helpers['gvars'] = true
|
|
1425
|
-
"__gvars[#{gvar.inspect}]"
|
|
1573
|
+
fragment("__gvars[#{gvar.inspect}]", sexp)
|
|
1426
1574
|
end
|
|
1427
|
-
|
|
1575
|
+
|
|
1428
1576
|
def process_nth_ref(sexp, level)
|
|
1429
|
-
"nil"
|
|
1577
|
+
fragment("nil", sexp)
|
|
1430
1578
|
end
|
|
1431
1579
|
|
|
1432
1580
|
# s(:gasgn, :gvar, rhs)
|
|
@@ -1434,7 +1582,7 @@ module Opal
|
|
|
1434
1582
|
gvar = sexp[0].to_s[1..-1]
|
|
1435
1583
|
rhs = sexp[1]
|
|
1436
1584
|
@helpers['gvars'] = true
|
|
1437
|
-
"__gvars[#{gvar.to_s.inspect}] =
|
|
1585
|
+
[fragment("__gvars[#{gvar.to_s.inspect}] = ", sexp), process(rhs, :expr)]
|
|
1438
1586
|
end
|
|
1439
1587
|
|
|
1440
1588
|
# s(:const, :const)
|
|
@@ -1443,17 +1591,17 @@ module Opal
|
|
|
1443
1591
|
|
|
1444
1592
|
if @const_missing
|
|
1445
1593
|
with_temp do |t|
|
|
1446
|
-
"((#{t} = __scope.#{cname}) == null ? __opal.cm(#{cname.inspect}) : #{t})"
|
|
1594
|
+
fragment("((#{t} = __scope.#{cname}) == null ? __opal.cm(#{cname.inspect}) : #{t})", sexp)
|
|
1447
1595
|
end
|
|
1448
1596
|
else
|
|
1449
|
-
"__scope.#{cname}"
|
|
1597
|
+
fragment("__scope.#{cname}", sexp)
|
|
1450
1598
|
end
|
|
1451
1599
|
end
|
|
1452
1600
|
|
|
1453
1601
|
# s(:cdecl, :const, rhs)
|
|
1454
1602
|
def process_cdecl(sexp, level)
|
|
1455
1603
|
const, rhs = sexp
|
|
1456
|
-
"__scope.#{const} =
|
|
1604
|
+
[fragment("__scope.#{const} = ", sexp), process(rhs, :expr)]
|
|
1457
1605
|
end
|
|
1458
1606
|
|
|
1459
1607
|
# s(:return [val])
|
|
@@ -1461,67 +1609,91 @@ module Opal
|
|
|
1461
1609
|
val = process(sexp.shift || s(:nil), :expr)
|
|
1462
1610
|
|
|
1463
1611
|
raise SyntaxError, "void value expression: cannot return as an expression" unless level == :stmt
|
|
1464
|
-
"return
|
|
1612
|
+
[fragment("return ", sexp), val]
|
|
1465
1613
|
end
|
|
1466
1614
|
|
|
1467
1615
|
# s(:xstr, content)
|
|
1468
1616
|
def process_xstr(sexp, level)
|
|
1469
1617
|
code = sexp.first.to_s
|
|
1470
1618
|
code += ";" if level == :stmt and !code.include?(';')
|
|
1471
|
-
|
|
1619
|
+
|
|
1620
|
+
result = fragment(code, sexp)
|
|
1621
|
+
|
|
1622
|
+
level == :recv ? [fragment("(", sexp), result, fragment(")", sexp)] : result
|
|
1472
1623
|
end
|
|
1473
1624
|
|
|
1474
1625
|
# s(:dxstr, parts...)
|
|
1475
1626
|
def process_dxstr(sexp, level)
|
|
1476
|
-
|
|
1627
|
+
result = []
|
|
1628
|
+
needs_sc = false
|
|
1629
|
+
|
|
1630
|
+
sexp.each do |p|
|
|
1477
1631
|
if String === p
|
|
1478
|
-
p.to_s
|
|
1632
|
+
result << fragment(p.to_s, sexp)
|
|
1633
|
+
needs_sc = true if level == :stmt and !p.to_s.include?(';')
|
|
1479
1634
|
elsif p.first == :evstr
|
|
1480
|
-
process
|
|
1635
|
+
result.push(*process(p.last, :stmt))
|
|
1481
1636
|
elsif p.first == :str
|
|
1482
|
-
p.last.to_s
|
|
1637
|
+
result << fragment(p.last.to_s, p)
|
|
1638
|
+
needs_sc = true if level == :stmt and !p.last.to_s.include?(';')
|
|
1483
1639
|
else
|
|
1484
1640
|
raise "Bad dxstr part"
|
|
1485
1641
|
end
|
|
1486
|
-
end
|
|
1642
|
+
end
|
|
1487
1643
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1644
|
+
result << fragment(";", sexp) if needs_sc
|
|
1645
|
+
|
|
1646
|
+
if level == :recv
|
|
1647
|
+
[fragment("(", sexp), result, fragment(")", sexp)]
|
|
1648
|
+
else
|
|
1649
|
+
result
|
|
1650
|
+
end
|
|
1491
1651
|
end
|
|
1492
1652
|
|
|
1493
1653
|
# s(:dstr, parts..)
|
|
1494
1654
|
def process_dstr(sexp, level)
|
|
1495
|
-
|
|
1655
|
+
result = []
|
|
1656
|
+
|
|
1657
|
+
sexp.each do |p|
|
|
1658
|
+
result << fragment(" + ", sexp) unless result.empty?
|
|
1496
1659
|
if String === p
|
|
1497
|
-
p.inspect
|
|
1660
|
+
result << fragment(p.inspect, sexp)
|
|
1498
1661
|
elsif p.first == :evstr
|
|
1499
|
-
"("
|
|
1662
|
+
result << fragment("(", p)
|
|
1663
|
+
result << process(p.last, :expr)
|
|
1664
|
+
result << fragment(")", p)
|
|
1500
1665
|
elsif p.first == :str
|
|
1501
|
-
p.last.inspect
|
|
1666
|
+
result << fragment(p.last.inspect, p)
|
|
1502
1667
|
else
|
|
1503
1668
|
raise "Bad dstr part"
|
|
1504
1669
|
end
|
|
1505
1670
|
end
|
|
1506
1671
|
|
|
1507
|
-
|
|
1508
|
-
|
|
1672
|
+
if level == :recv
|
|
1673
|
+
[fragment("(", sexp), result, fragment(")", sexp)]
|
|
1674
|
+
else
|
|
1675
|
+
result
|
|
1676
|
+
end
|
|
1509
1677
|
end
|
|
1510
1678
|
|
|
1511
1679
|
def process_dsym(sexp, level)
|
|
1512
|
-
|
|
1680
|
+
result = []
|
|
1681
|
+
|
|
1682
|
+
sexp.each do |p|
|
|
1683
|
+
result << fragment(" + ", sexp) unless result.empty?
|
|
1684
|
+
|
|
1513
1685
|
if String === p
|
|
1514
|
-
p.inspect
|
|
1686
|
+
result << fragment(p.inspect, sexp)
|
|
1515
1687
|
elsif p.first == :evstr
|
|
1516
|
-
process(s(:call, p.last, :to_s, s(:arglist)), :expr)
|
|
1688
|
+
result << process(s(:call, p.last, :to_s, s(:arglist)), :expr)
|
|
1517
1689
|
elsif p.first == :str
|
|
1518
|
-
p.last.inspect
|
|
1690
|
+
result << fragment(p.last.inspect, sexp)
|
|
1519
1691
|
else
|
|
1520
1692
|
raise "Bad dsym part"
|
|
1521
1693
|
end
|
|
1522
1694
|
end
|
|
1523
1695
|
|
|
1524
|
-
"(
|
|
1696
|
+
[fragment("(", sexp), result, fragment(")", sexp)]
|
|
1525
1697
|
end
|
|
1526
1698
|
|
|
1527
1699
|
# s(:if, test, truthy, falsy)
|
|
@@ -1543,14 +1715,21 @@ module Opal
|
|
|
1543
1715
|
check = js_truthy test
|
|
1544
1716
|
end
|
|
1545
1717
|
|
|
1546
|
-
|
|
1547
|
-
indent { code += @indent + process(truthy, :stmt) } if truthy
|
|
1548
|
-
indent { code += "\n#@indent} else {\n#@indent#{process falsy, :stmt}" } if falsy
|
|
1549
|
-
code += "\n#@indent}"
|
|
1718
|
+
result = [fragment("if (", sexp), check, fragment(") {\n", sexp)]
|
|
1550
1719
|
|
|
1551
|
-
|
|
1720
|
+
indent { result.push(fragment(@indent, sexp), process(truthy, :stmt)) } if truthy
|
|
1552
1721
|
|
|
1553
|
-
|
|
1722
|
+
outdent = @indent
|
|
1723
|
+
indent { result.push(fragment("\n#{outdent}} else {\n#@indent", sexp), process(falsy, :stmt)) } if falsy
|
|
1724
|
+
|
|
1725
|
+
result << fragment("\n#@indent}", sexp)
|
|
1726
|
+
|
|
1727
|
+
if returnable
|
|
1728
|
+
result.unshift fragment("(function() { ", sexp)
|
|
1729
|
+
result.push fragment("; return nil; }).call(#{current_self})", sexp)
|
|
1730
|
+
end
|
|
1731
|
+
|
|
1732
|
+
result
|
|
1554
1733
|
end
|
|
1555
1734
|
|
|
1556
1735
|
def js_truthy_optimize(sexp)
|
|
@@ -1564,8 +1743,7 @@ module Opal
|
|
|
1564
1743
|
return process sexp, :expr
|
|
1565
1744
|
end
|
|
1566
1745
|
elsif [:lvar, :self].include? sexp.first
|
|
1567
|
-
|
|
1568
|
-
"#{name} !== false && #{name} !== nil"
|
|
1746
|
+
[process(sexp.dup, :expr), fragment(" !== false && ", sexp), process(sexp.dup, :expr), fragment(" !== nil", sexp)]
|
|
1569
1747
|
end
|
|
1570
1748
|
end
|
|
1571
1749
|
|
|
@@ -1575,7 +1753,7 @@ module Opal
|
|
|
1575
1753
|
end
|
|
1576
1754
|
|
|
1577
1755
|
with_temp do |tmp|
|
|
1578
|
-
"(
|
|
1756
|
+
[fragment("(#{tmp} = ", sexp), process(sexp, :expr), fragment(") !== false && #{tmp} !== nil", sexp)]
|
|
1579
1757
|
end
|
|
1580
1758
|
end
|
|
1581
1759
|
|
|
@@ -1588,7 +1766,11 @@ module Opal
|
|
|
1588
1766
|
end
|
|
1589
1767
|
|
|
1590
1768
|
with_temp do |tmp|
|
|
1591
|
-
|
|
1769
|
+
result = []
|
|
1770
|
+
result << fragment("(#{tmp} = ", sexp)
|
|
1771
|
+
result << process(sexp, :expr)
|
|
1772
|
+
result << fragment(") === false || #{tmp} === nil", sexp)
|
|
1773
|
+
result
|
|
1592
1774
|
end
|
|
1593
1775
|
end
|
|
1594
1776
|
|
|
@@ -1599,26 +1781,30 @@ module Opal
|
|
|
1599
1781
|
tmp = @scope.new_temp
|
|
1600
1782
|
|
|
1601
1783
|
if t = js_truthy_optimize(lhs)
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1784
|
+
result = []
|
|
1785
|
+
result << fragment("((#{tmp} = ", sexp) << t
|
|
1786
|
+
result << fragment(") ? ", sexp) << process(rhs, :expr)
|
|
1787
|
+
result << fragment(" : #{tmp})", sexp)
|
|
1788
|
+
@scope.queue_temp tmp
|
|
1789
|
+
|
|
1790
|
+
return result
|
|
1605
1791
|
end
|
|
1606
1792
|
|
|
1607
1793
|
@scope.queue_temp tmp
|
|
1608
1794
|
|
|
1609
|
-
"(
|
|
1610
|
-
|
|
1795
|
+
[fragment("(#{tmp} = ", sexp), process(lhs, :expr), fragment(", #{tmp} !== false && #{tmp} !== nil ? ", sexp), process(rhs, :expr), fragment(" : #{tmp})", sexp)]
|
|
1796
|
+
|
|
1611
1797
|
end
|
|
1612
1798
|
|
|
1613
1799
|
# s(:or, lhs, rhs)
|
|
1614
1800
|
def process_or(sexp, level)
|
|
1615
1801
|
lhs = sexp[0]
|
|
1616
1802
|
rhs = sexp[1]
|
|
1617
|
-
t = nil
|
|
1618
1803
|
|
|
1619
1804
|
with_temp do |tmp|
|
|
1620
|
-
|
|
1621
|
-
|
|
1805
|
+
lhs = process lhs, :expr
|
|
1806
|
+
rhs = process rhs, :expr
|
|
1807
|
+
[fragment("(#{tmp} = ", sexp), lhs, fragment(", #{tmp} !== false && #{tmp} !== nil ? #{tmp} : ", sexp), rhs, fragment(")", sexp)]
|
|
1622
1808
|
end
|
|
1623
1809
|
end
|
|
1624
1810
|
|
|
@@ -1627,10 +1813,10 @@ module Opal
|
|
|
1627
1813
|
call = handle_yield_call sexp, level
|
|
1628
1814
|
|
|
1629
1815
|
if level == :stmt
|
|
1630
|
-
"if (
|
|
1816
|
+
[fragment("if (", sexp), call, fragment(" === __breaker) return __breaker.$v")]
|
|
1631
1817
|
else
|
|
1632
1818
|
with_temp do |tmp|
|
|
1633
|
-
"(((#{tmp} =
|
|
1819
|
+
[fragment("(((#{tmp} = ", sexp), call, fragment(") === __breaker) ? __breaker.$v : #{tmp})", sexp)]
|
|
1634
1820
|
end
|
|
1635
1821
|
end
|
|
1636
1822
|
end
|
|
@@ -1643,7 +1829,8 @@ module Opal
|
|
|
1643
1829
|
# s(:yasgn, :a, s(:yield, arg1, arg2))
|
|
1644
1830
|
def process_yasgn(sexp, level)
|
|
1645
1831
|
call = handle_yield_call s(*sexp[1][1..-1]), :stmt
|
|
1646
|
-
|
|
1832
|
+
|
|
1833
|
+
[fragment("if ((#{sexp[0]} = ", sexp), call, fragment(") === __breaker) return __breaker.$v", sexp)]
|
|
1647
1834
|
end
|
|
1648
1835
|
|
|
1649
1836
|
# Created by `#returns()` for when a yield statement should return
|
|
@@ -1652,8 +1839,8 @@ module Opal
|
|
|
1652
1839
|
call = handle_yield_call sexp, level
|
|
1653
1840
|
|
|
1654
1841
|
with_temp do |tmp|
|
|
1655
|
-
"return
|
|
1656
|
-
|
|
1842
|
+
[fragment("return #{tmp} = ", sexp), call,
|
|
1843
|
+
fragment(", #{tmp} === __breaker ? #{tmp} : #{tmp}")]
|
|
1657
1844
|
end
|
|
1658
1845
|
end
|
|
1659
1846
|
|
|
@@ -1666,16 +1853,20 @@ module Opal
|
|
|
1666
1853
|
|
|
1667
1854
|
y = @scope.block_name || '__yield'
|
|
1668
1855
|
|
|
1669
|
-
splat
|
|
1856
|
+
if splat
|
|
1857
|
+
[fragment("#{y}.apply(null, ", sexp), args, fragment(")", sexp)]
|
|
1858
|
+
else
|
|
1859
|
+
[fragment("#{y}.call(", sexp), args, fragment(")", sexp)]
|
|
1860
|
+
end
|
|
1670
1861
|
end
|
|
1671
1862
|
|
|
1672
|
-
def process_break(
|
|
1673
|
-
val =
|
|
1863
|
+
def process_break(sexp, level)
|
|
1864
|
+
val = sexp.empty? ? fragment('nil', sexp) : process(sexp.shift, :expr)
|
|
1674
1865
|
if in_while?
|
|
1675
|
-
@while_loop[:closure] ? "return
|
|
1866
|
+
@while_loop[:closure] ? [fragment("return ", sexp), val, fragment("", sexp)] : fragment("break;", sexp)
|
|
1676
1867
|
elsif @scope.iter?
|
|
1677
1868
|
error "break must be used as a statement" unless level == :stmt
|
|
1678
|
-
"return (__breaker.$v =
|
|
1869
|
+
[fragment("return (__breaker.$v = ", sexp), val, fragment(", __breaker)", sexp)]
|
|
1679
1870
|
else
|
|
1680
1871
|
error "void value expression: cannot use break outside of iter/while"
|
|
1681
1872
|
end
|
|
@@ -1683,6 +1874,7 @@ module Opal
|
|
|
1683
1874
|
|
|
1684
1875
|
# s(:case, expr, when1, when2, ..)
|
|
1685
1876
|
def process_case(exp, level)
|
|
1877
|
+
pre = []
|
|
1686
1878
|
code = []
|
|
1687
1879
|
@scope.add_local "$case"
|
|
1688
1880
|
expr = process exp.shift, :expr
|
|
@@ -1690,24 +1882,31 @@ module Opal
|
|
|
1690
1882
|
returnable = level != :stmt
|
|
1691
1883
|
done_else = false
|
|
1692
1884
|
|
|
1885
|
+
pre << fragment("$case = ", exp) << expr << fragment(";", exp)
|
|
1886
|
+
|
|
1693
1887
|
until exp.empty?
|
|
1694
1888
|
wen = exp.shift
|
|
1695
1889
|
if wen and wen.first == :when
|
|
1696
1890
|
returns(wen) if returnable
|
|
1697
1891
|
wen = process(wen, :stmt)
|
|
1698
|
-
|
|
1892
|
+
code << fragment("else ", exp) unless code.empty?
|
|
1699
1893
|
code << wen
|
|
1700
1894
|
elsif wen # s(:else)
|
|
1701
1895
|
done_else = true
|
|
1702
1896
|
wen = returns(wen) if returnable
|
|
1703
|
-
code << "else {
|
|
1897
|
+
code << fragment("else {", exp) << process(wen, :stmt) << fragment("}", exp)
|
|
1704
1898
|
end
|
|
1705
1899
|
end
|
|
1706
1900
|
|
|
1707
|
-
code << "else {return nil}" if returnable and !done_else
|
|
1901
|
+
code << fragment("else { return nil }", exp) if returnable and !done_else
|
|
1902
|
+
|
|
1903
|
+
code.unshift pre
|
|
1904
|
+
|
|
1905
|
+
if returnable
|
|
1906
|
+
code.unshift fragment("(function() { ", exp)
|
|
1907
|
+
code << fragment(" }).call(#{current_self})", exp)
|
|
1908
|
+
end
|
|
1708
1909
|
|
|
1709
|
-
code = "$case = #{expr};#{code.join @space}"
|
|
1710
|
-
code = "(function() { #{code} }).call(#{current_self})" if returnable
|
|
1711
1910
|
code
|
|
1712
1911
|
end
|
|
1713
1912
|
|
|
@@ -1717,30 +1916,32 @@ module Opal
|
|
|
1717
1916
|
# s(:when, s(:array, foo), bar)
|
|
1718
1917
|
def process_when(exp, level)
|
|
1719
1918
|
arg = exp.shift[1..-1]
|
|
1720
|
-
body = exp.shift
|
|
1721
|
-
body = process body, level if body
|
|
1919
|
+
body = exp.shift || s(:nil)
|
|
1920
|
+
#body = process body, level if body
|
|
1921
|
+
body = process body, level
|
|
1722
1922
|
|
|
1723
1923
|
test = []
|
|
1724
1924
|
until arg.empty?
|
|
1925
|
+
test << fragment(" || ", exp) unless test.empty?
|
|
1725
1926
|
a = arg.shift
|
|
1726
1927
|
|
|
1727
1928
|
if a.first == :splat # when inside another when means a splat of values
|
|
1728
|
-
call
|
|
1729
|
-
splt
|
|
1730
|
-
splt
|
|
1731
|
-
splt
|
|
1929
|
+
call = s(:call, s(:js_tmp, "$splt[i]"), :===, s(:arglist, s(:js_tmp, "$case")))
|
|
1930
|
+
splt = [fragment("(function($splt) { for(var i = 0; i < $splt.length; i++) {", exp)]
|
|
1931
|
+
splt << fragment("if (", exp) << process(call, :expr) << fragment(") { return true; }", exp)
|
|
1932
|
+
splt << fragment("} return false; }).call(#{current_self}, ", exp)
|
|
1933
|
+
splt << process(a[1], :expr) << fragment(")", exp)
|
|
1732
1934
|
|
|
1733
1935
|
test << splt
|
|
1734
1936
|
else
|
|
1735
1937
|
call = s(:call, a, :===, s(:arglist, s(:js_tmp, "$case")))
|
|
1736
1938
|
call = process call, :expr
|
|
1737
|
-
# call = "else " unless test.empty?
|
|
1738
1939
|
|
|
1739
1940
|
test << call
|
|
1740
1941
|
end
|
|
1741
1942
|
end
|
|
1742
1943
|
|
|
1743
|
-
"if (
|
|
1944
|
+
[fragment("if (", exp), test, fragment(") {#@space", exp), body, fragment("#@space}", exp)]
|
|
1744
1945
|
end
|
|
1745
1946
|
|
|
1746
1947
|
# lhs =~ rhs
|
|
@@ -1758,8 +1959,8 @@ module Opal
|
|
|
1758
1959
|
# s(:cvar, name)
|
|
1759
1960
|
def process_cvar(exp, level)
|
|
1760
1961
|
with_temp do |tmp|
|
|
1761
|
-
"((%s = Opal.cvars[%s]) == null ? nil : %s)" %
|
|
1762
|
-
[tmp, exp.shift.to_s.inspect, tmp]
|
|
1962
|
+
fragment(("((%s = Opal.cvars[%s]) == null ? nil : %s)" %
|
|
1963
|
+
[tmp, exp.shift.to_s.inspect, tmp]), exp)
|
|
1763
1964
|
end
|
|
1764
1965
|
end
|
|
1765
1966
|
|
|
@@ -1771,7 +1972,7 @@ module Opal
|
|
|
1771
1972
|
end
|
|
1772
1973
|
|
|
1773
1974
|
def process_cvdecl(exp, level)
|
|
1774
|
-
"(Opal.cvars[#{exp.shift.to_s.inspect}] =
|
|
1975
|
+
[fragment("(Opal.cvars[#{exp.shift.to_s.inspect}] = ", exp), process(exp.shift, :expr), fragment(")", exp)]
|
|
1775
1976
|
end
|
|
1776
1977
|
|
|
1777
1978
|
# BASE::NAME
|
|
@@ -1780,22 +1981,28 @@ module Opal
|
|
|
1780
1981
|
def process_colon2(sexp, level)
|
|
1781
1982
|
base = sexp[0]
|
|
1782
1983
|
cname = sexp[1].to_s
|
|
1984
|
+
result = []
|
|
1783
1985
|
|
|
1784
1986
|
if @const_missing
|
|
1785
1987
|
with_temp do |t|
|
|
1786
|
-
|
|
1787
|
-
|
|
1988
|
+
base = process base, :expr
|
|
1989
|
+
|
|
1990
|
+
result << fragment("((#{t} = (", sexp) << base << fragment(")._scope).", sexp)
|
|
1991
|
+
result << fragment("#{cname} == null ? #{t}.cm(#{cname.inspect}) : #{t}.#{cname})", sexp)
|
|
1788
1992
|
end
|
|
1789
1993
|
else
|
|
1790
1994
|
base = process base, :expr
|
|
1791
|
-
|
|
1995
|
+
|
|
1996
|
+
result << fragment("(", sexp) << base << fragment(")._scope.#{cname}", sexp)
|
|
1792
1997
|
end
|
|
1998
|
+
|
|
1999
|
+
result
|
|
1793
2000
|
end
|
|
1794
2001
|
|
|
1795
2002
|
def process_colon3(exp, level)
|
|
1796
2003
|
with_temp do |t|
|
|
1797
2004
|
cname = exp.shift.to_s
|
|
1798
|
-
"((#{t} = __opal.Object._scope.#{cname}) == null ? __opal.cm(#{cname.inspect}) : #{t})"
|
|
2005
|
+
fragment("((#{t} = __opal.Object._scope.#{cname}) == null ? __opal.cm(#{cname.inspect}) : #{t})", exp)
|
|
1799
2006
|
end
|
|
1800
2007
|
end
|
|
1801
2008
|
|
|
@@ -1805,42 +2012,45 @@ module Opal
|
|
|
1805
2012
|
def process_super(sexp, level)
|
|
1806
2013
|
args = []
|
|
1807
2014
|
until sexp.empty?
|
|
2015
|
+
args << fragment(", ", sexp) unless args.empty?
|
|
1808
2016
|
args << process(sexp.shift, :expr)
|
|
1809
2017
|
end
|
|
1810
2018
|
|
|
1811
|
-
js_super "[
|
|
2019
|
+
js_super [fragment("[", sexp), args, fragment("]", sexp)], sexp
|
|
1812
2020
|
end
|
|
1813
2021
|
|
|
1814
2022
|
# super
|
|
1815
2023
|
#
|
|
1816
2024
|
# s(:zsuper)
|
|
1817
2025
|
def process_zsuper(exp, level)
|
|
1818
|
-
js_super "__slice.call(arguments)"
|
|
2026
|
+
js_super fragment("__slice.call(arguments)", exp), exp
|
|
1819
2027
|
end
|
|
1820
2028
|
|
|
1821
|
-
def js_super args
|
|
2029
|
+
def js_super args, sexp
|
|
1822
2030
|
if @scope.def_in_class?
|
|
1823
2031
|
mid = @scope.mid.to_s
|
|
1824
2032
|
sid = "super_#{unique_temp}"
|
|
1825
2033
|
|
|
1826
2034
|
@scope.uses_super = sid
|
|
1827
|
-
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
[fragment("#{sid}.apply(#{current_self}, ", sexp), args, fragment(")", sexp)]
|
|
1828
2038
|
|
|
1829
2039
|
elsif @scope.type == :def
|
|
1830
|
-
|
|
1831
|
-
cls_name = @scope.parent.name || "#{current_self}.
|
|
2040
|
+
@scope.identify!
|
|
2041
|
+
cls_name = @scope.parent.name || "#{current_self}.constructor.prototype"
|
|
1832
2042
|
jsid = mid_to_jsid @scope.mid.to_s
|
|
1833
2043
|
|
|
1834
2044
|
if @scope.defs
|
|
1835
|
-
"%s._super%s.apply(this,
|
|
2045
|
+
[fragment(("%s._super%s.apply(this, " % [cls_name, jsid]), sexp), args, fragment(")", sexp)]
|
|
1836
2046
|
else
|
|
1837
|
-
"#{current_self}.
|
|
2047
|
+
[fragment("#{current_self}.constructor._super.prototype#{jsid}.apply(#{current_self}, ", sexp), args, fragment(")", sexp)]
|
|
1838
2048
|
end
|
|
1839
2049
|
|
|
1840
2050
|
elsif @scope.type == :iter
|
|
1841
2051
|
chain, defn, mid = @scope.get_super_chain
|
|
1842
2052
|
trys = chain.map { |c| "#{c}._sup" }.join ' || '
|
|
1843
|
-
"(#{trys} || #{current_self}.
|
|
2053
|
+
[fragment("(#{trys} || #{current_self}.constructor._super.prototype[#{mid}]).apply(#{current_self}, ", sexp), args, fragment(")", sexp)]
|
|
1844
2054
|
else
|
|
1845
2055
|
raise "Cannot call super() from outside a method block"
|
|
1846
2056
|
end
|
|
@@ -1875,7 +2085,11 @@ module Opal
|
|
|
1875
2085
|
aset = s(:call, s(:js_tmp, r), :[]=, s(:arglist, s(:js_tmp, a), rhs))
|
|
1876
2086
|
orop = s(:or, aref, aset)
|
|
1877
2087
|
|
|
1878
|
-
|
|
2088
|
+
result = []
|
|
2089
|
+
result << fragment("(#{a} = ", sexp) << args << fragment(", #{r} = ", sexp)
|
|
2090
|
+
result << recv << fragment(", ", sexp) << process(orop, :expr)
|
|
2091
|
+
result << fragment(")", sexp)
|
|
2092
|
+
result
|
|
1879
2093
|
end
|
|
1880
2094
|
end
|
|
1881
2095
|
end
|
|
@@ -1883,11 +2097,11 @@ module Opal
|
|
|
1883
2097
|
# lhs.b += rhs
|
|
1884
2098
|
#
|
|
1885
2099
|
# s(:op_asgn2, lhs, :b=, :+, rhs)
|
|
1886
|
-
def process_op_asgn2(
|
|
1887
|
-
lhs = process
|
|
1888
|
-
mid =
|
|
1889
|
-
op =
|
|
1890
|
-
rhs =
|
|
2100
|
+
def process_op_asgn2(sexp, level)
|
|
2101
|
+
lhs = process sexp.shift, :expr
|
|
2102
|
+
mid = sexp.shift.to_s[0..-2]
|
|
2103
|
+
op = sexp.shift
|
|
2104
|
+
rhs = sexp.shift
|
|
1891
2105
|
|
|
1892
2106
|
if op.to_s == "||"
|
|
1893
2107
|
with_temp do |temp|
|
|
@@ -1895,7 +2109,7 @@ module Opal
|
|
|
1895
2109
|
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, rhs))
|
|
1896
2110
|
orop = s(:or, getr, asgn)
|
|
1897
2111
|
|
|
1898
|
-
"(#{temp} =
|
|
2112
|
+
[fragment("(#{temp} = ", sexp), lhs, fragment(", ", sexp), process(orop, :expr), fragment(")", sexp)]
|
|
1899
2113
|
end
|
|
1900
2114
|
elsif op.to_s == '&&'
|
|
1901
2115
|
with_temp do |temp|
|
|
@@ -1903,7 +2117,7 @@ module Opal
|
|
|
1903
2117
|
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, rhs))
|
|
1904
2118
|
andop = s(:and, getr, asgn)
|
|
1905
2119
|
|
|
1906
|
-
"(#{temp} =
|
|
2120
|
+
[fragment("(#{temp} = ", sexp), lhs, fragment(", ", sexp), process(andop, :expr), fragment(")", sexp)]
|
|
1907
2121
|
end
|
|
1908
2122
|
else
|
|
1909
2123
|
with_temp do |temp|
|
|
@@ -1911,7 +2125,7 @@ module Opal
|
|
|
1911
2125
|
oper = s(:call, getr, op, s(:arglist, rhs))
|
|
1912
2126
|
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, oper))
|
|
1913
2127
|
|
|
1914
|
-
"(#{temp} =
|
|
2128
|
+
[fragment("(#{temp} = ", sexp), lhs, fragment(", ", sexp), process(asgn, :expr), fragment(")", sexp)]
|
|
1915
2129
|
end
|
|
1916
2130
|
end
|
|
1917
2131
|
end
|
|
@@ -1924,14 +2138,20 @@ module Opal
|
|
|
1924
2138
|
begn = returns begn
|
|
1925
2139
|
end
|
|
1926
2140
|
|
|
2141
|
+
result = []
|
|
1927
2142
|
body = process begn, level
|
|
1928
2143
|
ensr = exp.shift || s(:nil)
|
|
1929
2144
|
ensr = process ensr, level
|
|
1930
|
-
body = "try {\n#{body}}" unless body =~ /^try \{/
|
|
1931
2145
|
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
2146
|
+
body = [fragment("try {\n", exp), body, fragment("}", exp)]
|
|
2147
|
+
|
|
2148
|
+
result << body << fragment("#{@space}finally {#@space", exp) << ensr << fragment("}", exp)
|
|
2149
|
+
|
|
2150
|
+
if retn
|
|
2151
|
+
[fragment("(function() { ", exp), result, fragment("; }).call(#{current_self})", exp)]
|
|
2152
|
+
else
|
|
2153
|
+
result
|
|
2154
|
+
end
|
|
1935
2155
|
end
|
|
1936
2156
|
|
|
1937
2157
|
def process_rescue(exp, level)
|
|
@@ -1943,14 +2163,27 @@ module Opal
|
|
|
1943
2163
|
until exp.empty?
|
|
1944
2164
|
handled_else = true unless exp.first.first == :resbody
|
|
1945
2165
|
part = indent { process exp.shift, level }
|
|
1946
|
-
|
|
2166
|
+
|
|
2167
|
+
unless parts.empty?
|
|
2168
|
+
parts << fragment("else ", exp)
|
|
2169
|
+
end
|
|
2170
|
+
|
|
1947
2171
|
parts << part
|
|
1948
2172
|
end
|
|
1949
2173
|
# if no rescue statement captures our error, we should rethrow
|
|
1950
|
-
parts << indent { "else { throw $err; }" } unless handled_else
|
|
2174
|
+
parts << indent { fragment("else { throw $err; }", exp) } unless handled_else
|
|
2175
|
+
|
|
2176
|
+
code = []
|
|
2177
|
+
code << fragment("try {#@space#{INDENT}", exp)
|
|
2178
|
+
code << body
|
|
2179
|
+
code << fragment("#@space} catch ($err) {#@space", exp)
|
|
2180
|
+
code << parts
|
|
2181
|
+
code << fragment("#@space}", exp)
|
|
1951
2182
|
|
|
1952
|
-
|
|
1953
|
-
|
|
2183
|
+
if level == :expr
|
|
2184
|
+
code.unshift fragment("(function() { ", exp)
|
|
2185
|
+
code << fragment(" }).call(#{current_self})", exp)
|
|
2186
|
+
end
|
|
1954
2187
|
|
|
1955
2188
|
code
|
|
1956
2189
|
end
|
|
@@ -1963,41 +2196,51 @@ module Opal
|
|
|
1963
2196
|
types = args[1..-1]
|
|
1964
2197
|
types.pop if types.last and types.last.first != :const
|
|
1965
2198
|
|
|
1966
|
-
err =
|
|
2199
|
+
err = []
|
|
2200
|
+
types.each do |t|
|
|
2201
|
+
err << fragment(", ", exp) unless err.empty?
|
|
1967
2202
|
call = s(:call, t, :===, s(:arglist, s(:js_tmp, "$err")))
|
|
1968
2203
|
a = process call, :expr
|
|
1969
|
-
a
|
|
1970
|
-
|
|
1971
|
-
err
|
|
2204
|
+
err << a
|
|
2205
|
+
end
|
|
2206
|
+
err << fragment("true", exp) if err.empty?
|
|
1972
2207
|
|
|
1973
2208
|
if Array === args.last and [:lasgn, :iasgn].include? args.last.first
|
|
1974
2209
|
val = args.last
|
|
1975
2210
|
val[2] = s(:js_tmp, "$err")
|
|
1976
|
-
val = process(val, :expr)
|
|
2211
|
+
val = [process(val, :expr) , fragment(";", exp)]
|
|
1977
2212
|
end
|
|
1978
2213
|
|
|
1979
|
-
|
|
2214
|
+
val = [] unless val
|
|
2215
|
+
|
|
2216
|
+
[fragment("if (", exp), err, fragment("){#@space", exp), val, body, fragment("}", exp)]
|
|
1980
2217
|
end
|
|
1981
2218
|
|
|
1982
2219
|
# FIXME: Hack.. grammar should remove top level begin.
|
|
1983
2220
|
def process_begin(exp, level)
|
|
1984
|
-
process exp[0], level
|
|
2221
|
+
result = process exp[0], level
|
|
1985
2222
|
end
|
|
1986
2223
|
|
|
1987
2224
|
def process_next(exp, level)
|
|
1988
2225
|
if in_while?
|
|
1989
|
-
"continue;"
|
|
2226
|
+
fragment("continue;", exp)
|
|
1990
2227
|
else
|
|
1991
|
-
|
|
2228
|
+
result = []
|
|
2229
|
+
result << fragment("return ", exp)
|
|
2230
|
+
|
|
2231
|
+
result << (exp.empty? ? fragment('nil', exp) : process(exp.shift, :expr))
|
|
2232
|
+
result << fragment(";", exp)
|
|
2233
|
+
|
|
2234
|
+
result
|
|
1992
2235
|
end
|
|
1993
2236
|
end
|
|
1994
2237
|
|
|
1995
2238
|
def process_redo(exp, level)
|
|
1996
2239
|
if in_while?
|
|
1997
2240
|
@while_loop[:use_redo] = true
|
|
1998
|
-
"#{@while_loop[:redo_var]} = true"
|
|
2241
|
+
fragment("#{@while_loop[:redo_var]} = true", exp)
|
|
1999
2242
|
else
|
|
2000
|
-
"REDO()"
|
|
2243
|
+
fragment("REDO()", exp)
|
|
2001
2244
|
end
|
|
2002
2245
|
end
|
|
2003
2246
|
end
|