opal 0.3.27 → 0.3.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/.gitignore +2 -1
  2. data/CONTRIBUTING.md +24 -0
  3. data/README.md +6 -5
  4. data/Rakefile +12 -2
  5. data/core/array.rb +3 -31
  6. data/core/enumerable.rb +32 -4
  7. data/core/hash.rb +218 -186
  8. data/core/json.rb +3 -2
  9. data/core/kernel.rb +28 -28
  10. data/core/numeric.rb +2 -2
  11. data/core/runtime.js +0 -1
  12. data/lib/opal.rb +4 -2
  13. data/lib/opal/grammar.rb +6 -2
  14. data/lib/opal/grammar.y +3 -0
  15. data/lib/opal/lexer.rb +25 -10
  16. data/lib/opal/parser.rb +75 -34
  17. data/lib/opal/scope.rb +7 -7
  18. data/lib/opal/version.rb +1 -1
  19. data/opal.gemspec +1 -1
  20. data/spec/core/array/reduce_spec.rb +31 -0
  21. data/spec/{opal → core}/array/to_json_spec.rb +0 -0
  22. data/spec/core/boolean/and_spec.rb +17 -0
  23. data/spec/core/boolean/inspect_spec.rb +9 -0
  24. data/spec/core/boolean/or_spec.rb +17 -0
  25. data/spec/{opal → core}/boolean/singleton_class_spec.rb +0 -0
  26. data/spec/{opal → core}/boolean/to_json_spec.rb +1 -1
  27. data/spec/core/boolean/to_s_spec.rb +9 -0
  28. data/spec/core/boolean/xor_spec.rb +17 -0
  29. data/spec/{opal → core}/class/bridge_class_spec.rb +0 -0
  30. data/spec/{opal → core}/class/instance_methods_spec.rb +0 -0
  31. data/spec/core/class/last_value_spec.rb +68 -0
  32. data/spec/core/enumerable/detect_spec.rb +1 -1
  33. data/spec/core/enumerable/find_spec.rb +1 -1
  34. data/spec/{opal → core}/hash/to_json_spec.rb +0 -0
  35. data/spec/{opal → core}/hash/to_native_spec.rb +0 -0
  36. data/spec/{opal → core}/json/parse_spec.rb +0 -0
  37. data/spec/core/kernel/block_given.rb +30 -0
  38. data/spec/core/kernel/methods_spec.rb +11 -0
  39. data/spec/core/kernel/p_spec.rb +13 -0
  40. data/spec/{opal → core}/kernel/to_json_spec.rb +0 -0
  41. data/spec/{opal → core}/nil/to_json_spec.rb +0 -0
  42. data/spec/core/numeric/abs_spec.rb +12 -0
  43. data/spec/core/numeric/bit_and_spec.rb +7 -0
  44. data/spec/core/numeric/bit_or_spec.rb +8 -0
  45. data/spec/core/numeric/bit_xor_spec.rb +6 -0
  46. data/spec/core/numeric/ceil_spec.rb +8 -0
  47. data/spec/core/numeric/chr_spec.rb +8 -0
  48. data/spec/core/numeric/comparison_spec.rb +24 -0
  49. data/spec/core/numeric/complement_spec.rb +8 -0
  50. data/spec/core/numeric/divide_spec.rb +10 -0
  51. data/spec/core/numeric/downto_spec.rb +19 -0
  52. data/spec/core/numeric/eql_spec.rb +9 -0
  53. data/spec/core/numeric/even_spec.rb +21 -0
  54. data/spec/core/numeric/exponent_spec.rb +33 -0
  55. data/spec/core/numeric/floor_spec.rb +8 -0
  56. data/spec/core/numeric/gt_spec.rb +11 -0
  57. data/spec/core/numeric/gte_spec.rb +12 -0
  58. data/spec/core/numeric/integer_spec.rb +9 -0
  59. data/spec/core/numeric/left_shift_spec.rb +21 -0
  60. data/spec/core/numeric/lt_spec.rb +11 -0
  61. data/spec/core/numeric/lte_spec.rb +12 -0
  62. data/spec/core/numeric/magnitude_spec.rb +12 -0
  63. data/spec/core/numeric/minus_spec.rb +8 -0
  64. data/spec/core/numeric/modulo_spec.rb +19 -0
  65. data/spec/core/numeric/multiply_spec.rb +9 -0
  66. data/spec/core/numeric/next_spec.rb +9 -0
  67. data/spec/core/numeric/odd_spec.rb +21 -0
  68. data/spec/core/numeric/ord_spec.rb +9 -0
  69. data/spec/core/numeric/plus_spec.rb +8 -0
  70. data/spec/core/numeric/pred_spec.rb +7 -0
  71. data/spec/core/numeric/right_shift_spec.rb +25 -0
  72. data/spec/core/numeric/succ_spec.rb +9 -0
  73. data/spec/core/numeric/times_spec.rb +36 -0
  74. data/spec/core/numeric/to_f_spec.rb +7 -0
  75. data/spec/core/numeric/to_i_spec.rb +7 -0
  76. data/spec/{opal → core}/numeric/to_json_spec.rb +0 -0
  77. data/spec/core/numeric/to_s_spec.rb +8 -0
  78. data/spec/core/numeric/uminus_spec.rb +9 -0
  79. data/spec/core/numeric/upto_spec.rb +19 -0
  80. data/spec/core/numeric/zero_spec.rb +7 -0
  81. data/spec/{opal → core}/runtime/call_spec.rb +0 -0
  82. data/spec/{opal → core}/runtime/class_hierarchy_spec.rb +0 -0
  83. data/spec/{opal → core}/runtime/def_spec.rb +0 -0
  84. data/spec/{opal → core}/runtime/defined_spec.rb +0 -0
  85. data/spec/{opal → core}/runtime/super_spec.rb +0 -0
  86. data/spec/{opal → core}/string/demodulize_spec.rb +0 -0
  87. data/spec/{opal → core}/string/to_json_spec.rb +0 -0
  88. data/spec/{opal → core}/string/underscore_spec.rb +0 -0
  89. data/spec/{opal → core}/strscan/check_spec.rb +0 -0
  90. data/spec/{opal → core}/strscan/scan_spec.rb +0 -0
  91. data/spec/{lib/grammar → grammar}/alias_spec.rb +0 -0
  92. data/spec/{lib/grammar → grammar}/and_spec.rb +0 -0
  93. data/spec/{lib/grammar → grammar}/array_spec.rb +0 -0
  94. data/spec/{lib/grammar → grammar}/attrasgn_spec.rb +0 -0
  95. data/spec/{lib/grammar → grammar}/begin_spec.rb +0 -0
  96. data/spec/{lib/grammar → grammar}/block_spec.rb +0 -0
  97. data/spec/{lib/grammar → grammar}/break_spec.rb +0 -0
  98. data/spec/{lib/grammar → grammar}/call_spec.rb +23 -1
  99. data/spec/{lib/grammar → grammar}/class_spec.rb +0 -0
  100. data/spec/{lib/grammar → grammar}/const_spec.rb +0 -0
  101. data/spec/{lib/grammar → grammar}/cvar_spec.rb +0 -0
  102. data/spec/{lib/grammar → grammar}/def_spec.rb +0 -0
  103. data/spec/{lib/grammar → grammar}/false_spec.rb +0 -0
  104. data/spec/{lib/grammar → grammar}/file_spec.rb +0 -0
  105. data/spec/{lib/grammar → grammar}/gvar_spec.rb +0 -0
  106. data/spec/{lib/grammar → grammar}/hash_spec.rb +0 -0
  107. data/spec/{lib/grammar → grammar}/iasgn_spec.rb +0 -0
  108. data/spec/{lib/grammar → grammar}/if_spec.rb +0 -0
  109. data/spec/{lib/grammar → grammar}/iter_spec.rb +0 -0
  110. data/spec/{lib/grammar → grammar}/ivar_spec.rb +0 -0
  111. data/spec/{lib/grammar → grammar}/lambda_spec.rb +0 -0
  112. data/spec/{lib/grammar → grammar}/lasgn_spec.rb +0 -0
  113. data/spec/{lib/grammar → grammar}/line_spec.rb +0 -0
  114. data/spec/{lib/grammar → grammar}/lvar_spec.rb +0 -0
  115. data/spec/{lib/grammar → grammar}/masgn_spec.rb +0 -0
  116. data/spec/{lib/grammar → grammar}/module_spec.rb +0 -0
  117. data/spec/{lib/grammar → grammar}/nil_spec.rb +0 -0
  118. data/spec/{lib/grammar → grammar}/not_spec.rb +0 -0
  119. data/spec/{lib/grammar → grammar}/op_asgn1_spec.rb +0 -0
  120. data/spec/{lib/grammar → grammar}/op_asgn2_spec.rb +0 -0
  121. data/spec/{lib/grammar → grammar}/or_spec.rb +0 -0
  122. data/spec/{lib/grammar → grammar}/return_spec.rb +0 -0
  123. data/spec/{lib/grammar → grammar}/sclass_spec.rb +0 -0
  124. data/spec/{lib/grammar → grammar}/self_spec.rb +0 -0
  125. data/spec/{lib/grammar → grammar}/str_spec.rb +7 -0
  126. data/spec/{lib/grammar → grammar}/super_spec.rb +0 -0
  127. data/spec/{lib/grammar → grammar}/true_spec.rb +0 -0
  128. data/spec/{lib/grammar → grammar}/undef_spec.rb +0 -0
  129. data/spec/{lib/grammar → grammar}/unless_spec.rb +0 -0
  130. data/spec/{lib/grammar → grammar}/while_spec.rb +0 -0
  131. data/spec/{lib/grammar → grammar}/xstr_spec.rb +0 -0
  132. data/spec/{lib/grammar → grammar}/yield_spec.rb +0 -0
  133. data/spec/language/string_spec.rb +5 -0
  134. data/spec/{lib/parser → parser}/simple_spec.rb +0 -0
  135. metadata +231 -159
  136. data/spec/core/false/and_spec.rb +0 -9
  137. data/spec/core/false/inspect_spec.rb +0 -5
  138. data/spec/core/false/or_spec.rb +0 -9
  139. data/spec/core/false/to_s_spec.rb +0 -5
  140. data/spec/core/false/xor_spec.rb +0 -9
  141. data/spec/core/true/and_spec.rb +0 -9
  142. data/spec/core/true/inspect_spec.rb +0 -5
  143. data/spec/core/true/or_spec.rb +0 -9
  144. data/spec/core/true/to_s_spec.rb +0 -5
  145. data/spec/core/true/xor_spec.rb +0 -9
  146. data/spec/lib/erb_parser/simple.erb +0 -1
  147. data/spec/opal/kernel/attribute_spec.rb +0 -57
  148. data/spec/opal/runtime/method_missing_spec.rb +0 -17
data/core/json.rb CHANGED
@@ -38,12 +38,13 @@ module JSON
38
38
  return arr;
39
39
  }
40
40
  else {
41
- var hash = #{ {} }, v, map = hash.map;
41
+ var hash = #{ {} }, v, map = hash.map, keys = hash.keys;
42
42
 
43
43
  for (var k in value) {
44
44
  if (__hasOwn.call(value, k)) {
45
45
  v = to_opal(value[k]);
46
- map[k] = [k, v];
46
+ keys.push(k);
47
+ map[k] = v;
47
48
  }
48
49
  }
49
50
  }
data/core/kernel.rb CHANGED
@@ -11,6 +11,23 @@ module Kernel
11
11
  `#{self} == other`
12
12
  end
13
13
 
14
+ def methods(all = true)
15
+ %x{
16
+ var methods = [];
17
+ for(var k in #{self}) {
18
+ if(k[0] == "$" && typeof (#{self})[k] === "function") {
19
+ if(all === #{false} || all === #{nil}) {
20
+ if(!Object.hasOwnProperty.call(#{self}, k)) {
21
+ continue;
22
+ }
23
+ }
24
+ methods.push(k.substr(1));
25
+ }
26
+ }
27
+ return methods;
28
+ }
29
+ end
30
+
14
31
  def __send__(symbol, *args, &block)
15
32
  %x{
16
33
  return #{self}['$' + symbol].apply(#{self}, args);
@@ -32,32 +49,6 @@ module Kernel
32
49
  }
33
50
  end
34
51
 
35
- def attribute_get(name)
36
- %x{
37
- var meth = '$' + name;
38
- if (#{self}[meth]) {
39
- return #{self}[meth]();
40
- }
41
-
42
- meth += '?';
43
- if (#{self}[meth]) {
44
- return #{self}[meth]()
45
- }
46
-
47
- return nil;
48
- }
49
- end
50
-
51
- def attribute_set(name, value)
52
- %x{
53
- if (#{self}['$' + name + '=']) {
54
- return #{self}['$' + name + '='](value);
55
- }
56
-
57
- return nil;
58
- }
59
- end
60
-
61
52
  def class
62
53
  `return #{self}._klass`
63
54
  end
@@ -103,7 +94,7 @@ module Kernel
103
94
  to_s
104
95
  end
105
96
 
106
- def instance_eval(string=undefined, &block)
97
+ def instance_eval(&block)
107
98
  %x{
108
99
  if (block === nil) {
109
100
  no_block_given();
@@ -206,12 +197,21 @@ module Kernel
206
197
  def puts(*strs)
207
198
  %x{
208
199
  for (var i = 0; i < strs.length; i++) {
209
- __opal.puts(#{ `strs[i]`.to_s });
200
+ if(strs[i] instanceof Array) {
201
+ #{ puts *strs }
202
+ } else {
203
+ __opal.puts(#{ `strs[i]`.to_s });
204
+ }
210
205
  }
211
206
  }
212
207
  nil
213
208
  end
214
209
 
210
+ def p(*args)
211
+ `console.log.apply(console, args);`
212
+ args.length <= 1 ? args[0] : args
213
+ end
214
+
215
215
  alias print puts
216
216
 
217
217
  def raise(exception, string)
data/core/numeric.rb CHANGED
@@ -161,7 +161,7 @@ class Numeric < `Number`
161
161
 
162
162
  def times(&block)
163
163
  %x{
164
- for (var i = 0; i <= #{self}; i++) {
164
+ for (var i = 0; i < #{self}; i++) {
165
165
  if (block.call(__context, i) === __breaker) {
166
166
  return __breaker.$v;
167
167
  }
@@ -189,7 +189,7 @@ class Numeric < `Number`
189
189
 
190
190
  def upto(finish, &block)
191
191
  %x{
192
- for (var i = 0; i <= finish; i++) {
192
+ for (var i = #{self}; i <= finish; i++) {
193
193
  if (block.call(__context, i) === __breaker) {
194
194
  return __breaker.$v;
195
195
  }
data/core/runtime.js CHANGED
@@ -89,7 +89,6 @@ Opal.module = function(base, id, constructor) {
89
89
  klass = boot_class(Class, constructor);
90
90
  klass._name = (base === Object ? id : base._name + '::' + id);
91
91
 
92
- klass._isModule = true;
93
92
  klass.$included_in = [];
94
93
 
95
94
  var const_alloc = function() {};
data/lib/opal.rb CHANGED
@@ -28,11 +28,13 @@ module Opal
28
28
  core_dir = Opal.core_dir
29
29
  load_order = File.join core_dir, 'load_order'
30
30
  corelib = File.read(load_order).strip.split.map do |c|
31
- File.read File.join(core_dir, "#{c}.rb")
31
+ file = File.join(core_dir, "#{c}.rb")
32
+ source = File.read file
33
+ Opal.parse source, file
32
34
  end
33
35
 
34
36
  runtime = File.read(File.join core_dir, 'runtime.js')
35
- corelib = Opal.parse corelib.join("\n"), '(corelib)'
37
+ corelib = corelib.join("\n")
36
38
 
37
39
  [
38
40
  "// Opal v#{Opal::VERSION}",
data/lib/opal/grammar.rb CHANGED
@@ -2091,7 +2091,7 @@ racc_reduce_table = [
2091
2091
  1, 186, :_reduce_none,
2092
2092
  0, 219, :_reduce_253,
2093
2093
  4, 186, :_reduce_254,
2094
- 4, 186, :_reduce_none,
2094
+ 4, 186, :_reduce_255,
2095
2095
  3, 186, :_reduce_256,
2096
2096
  3, 186, :_reduce_257,
2097
2097
  2, 186, :_reduce_258,
@@ -3817,7 +3817,11 @@ def _reduce_254(val, _values, result)
3817
3817
  result
3818
3818
  end
3819
3819
 
3820
- # reduce 255 omitted
3820
+ def _reduce_255(val, _values, result)
3821
+ result = val[1]
3822
+
3823
+ result
3824
+ end
3821
3825
 
3822
3826
  def _reduce_256(val, _values, result)
3823
3827
  result = val[1] || s(:nil)
data/lib/opal/grammar.y CHANGED
@@ -729,6 +729,9 @@ primary:
729
729
  result.line = val[1]
730
730
  }
731
731
  | tLPAREN_ARG expr opt_nl ')'
732
+ {
733
+ result = val[1]
734
+ }
732
735
  | PAREN_BEG compstmt ')'
733
736
  {
734
737
  result = val[1] || s(:nil)
data/lib/opal/lexer.rb CHANGED
@@ -7,10 +7,6 @@ class Array
7
7
  end
8
8
 
9
9
  module Opal
10
- Sexp = ::Array
11
-
12
- # Any exceptions with parsing of file will raise this error
13
- class OpalParseError < Exception; end
14
10
 
15
11
  class Grammar < Racc::Parser
16
12
 
@@ -27,7 +23,7 @@ module Opal
27
23
  end
28
24
 
29
25
  def s(*parts)
30
- sexp = Sexp.new(parts)
26
+ sexp = Array.new(parts)
31
27
  sexp.line = @line
32
28
  sexp
33
29
  end
@@ -43,7 +39,7 @@ module Opal
43
39
  end
44
40
 
45
41
  def on_error(t, val, vstack)
46
- raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
42
+ raise "parse error on value #{val.inspect} :#{@file}:#{@line}"
47
43
  end
48
44
 
49
45
  class LexerScope
@@ -731,6 +727,11 @@ module Opal
731
727
  return :OP_ASGN, '/'
732
728
  elsif @lex_state == :expr_fname
733
729
  @lex_state = :expr_end
730
+ elsif @lex_state == :expr_cmdarg || @lex_state == :expr_arg
731
+ if !scanner.check(/\s/) && space_seen
732
+ @string_parse = { :beg => '/', :end => '/', :interpolate => true, :regexp => true }
733
+ return :REGEXP_BEG, scanner.matched
734
+ end
734
735
  end
735
736
 
736
737
  return '/', '/'
@@ -747,7 +748,9 @@ module Opal
747
748
  result = scanner.matched
748
749
  if [:expr_beg, :expr_mid].include? @lex_state
749
750
  result = :PAREN_BEG
750
- elsif space_seen
751
+ elsif space_seen && [:expr_arg, :expr_cmdarg].include?(@lex_state)
752
+ result = :tLPAREN_ARG
753
+ else
751
754
  result = '('
752
755
  end
753
756
 
@@ -979,7 +982,7 @@ module Opal
979
982
  return '>=', scanner.matched
980
983
  elsif scanner.scan(/\>/)
981
984
  if @lex_state == :expr_fname
982
- @lex_state = :expr_end
985
+ @lex_state = :expr_arg
983
986
  else
984
987
  @lex_state = :expr_beg
985
988
  end
@@ -987,7 +990,8 @@ module Opal
987
990
  end
988
991
 
989
992
  elsif scanner.scan(/->/)
990
- @lex_state = :expr_arg
993
+ # FIXME: # should be :expr_arg, but '(' breaks it...
994
+ @lex_state = :expr_end
991
995
  @start_of_lambda = true
992
996
  return [:LAMBDA, scanner.matched]
993
997
 
@@ -1009,6 +1013,13 @@ module Opal
1009
1013
  return [:OP_ASGN, result]
1010
1014
  end
1011
1015
 
1016
+ if @lex_state == :expr_cmdarg || @lex_state == :expr_arg
1017
+ if !scanner.check(/\s/) && space_seen
1018
+ @lex_state = :expr_mid
1019
+ return [sign, sign]
1020
+ end
1021
+ end
1022
+
1012
1023
  @lex_state = :expr_beg
1013
1024
  return [result, result]
1014
1025
 
@@ -1019,6 +1030,10 @@ module Opal
1019
1030
  return '?', scanner.matched
1020
1031
  end
1021
1032
 
1033
+ unless scanner.check(/\ |\t|\r/)
1034
+ @lex_state = :expr_end
1035
+ return :STRING, scanner.scan(/./)
1036
+ end
1022
1037
  #if scanner.scan(/\\/)
1023
1038
  #c = if scanner.scan(/n/)
1024
1039
  #"\n"
@@ -1367,7 +1382,7 @@ module Opal
1367
1382
  end
1368
1383
  return [false, false] if scanner.eos?
1369
1384
 
1370
- raise OpalParseError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
1385
+ raise "Unexpected content in parsing stream `#{scanner.peek 5}` :#{@file}:#{@line}"
1371
1386
  end
1372
1387
  end
1373
1388
  end
data/lib/opal/parser.rb CHANGED
@@ -129,7 +129,7 @@ module Opal
129
129
  #
130
130
  # @result [Array]
131
131
  def s(*parts)
132
- sexp = Sexp.new(parts)
132
+ sexp = Array.new(parts)
133
133
  sexp.line = @line
134
134
  sexp
135
135
  end
@@ -339,6 +339,7 @@ module Opal
339
339
  sexp[0] = :returnable_yield
340
340
  sexp
341
341
  when :scope
342
+ sexp[1] = returns sexp[1]
342
343
  sexp
343
344
  when :block
344
345
  if sexp.length > 1
@@ -350,6 +351,9 @@ module Opal
350
351
  when :when
351
352
  sexp[2] = returns(sexp[2])
352
353
  sexp
354
+ when :rescue
355
+ sexp[1] = returns sexp[1]
356
+ sexp
353
357
  when :ensure
354
358
  sexp[1] = returns sexp[1]
355
359
  sexp
@@ -387,13 +391,13 @@ module Opal
387
391
  end
388
392
 
389
393
  # 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
394
+ # into a block sexp. A block sexp just holds any number of other
391
395
  # sexps.
392
396
  #
393
397
  # s(:block, s(:str, "hey"), s(:lit, 42))
394
398
  #
395
399
  # A block can actually be empty. As opal requires real values to
396
- # be returned (to appease javascript values), a nil sexp
400
+ # be returned (to appease javascript values), a nil sexp
397
401
  # s(:nil) will be generated if the block is empty.
398
402
  #
399
403
  # @return [String]
@@ -423,7 +427,7 @@ module Opal
423
427
  # generated as a top level member. This is because if a yield
424
428
  # is returned by a break statement, then the method must return.
425
429
  #
426
- # As inline expressions in javascript cannot return, the block
430
+ # As inline expressions in javascript cannot return, the block
427
431
  # must be rewritten.
428
432
  #
429
433
  # For example, a yield inside an array:
@@ -470,7 +474,7 @@ module Opal
470
474
  def process_scope(sexp, level)
471
475
  stmt = sexp.shift
472
476
  if stmt
473
- stmt = returns stmt unless @scope.donates_methods
477
+ stmt = returns stmt unless @scope.class_scope?
474
478
  code = process stmt, :stmt
475
479
  else
476
480
  code = "nil"
@@ -506,7 +510,11 @@ module Opal
506
510
 
507
511
  def js_block_given(sexp, level)
508
512
  @scope.uses_block!
509
- "(#{@scope.block_name} !== nil)"
513
+ if @scope.block_name
514
+ "(#{@scope.block_name} !== nil)"
515
+ else
516
+ "false"
517
+ end
510
518
  end
511
519
 
512
520
  def handle_block_given(sexp, reverse = false)
@@ -601,8 +609,11 @@ module Opal
601
609
 
602
610
  # s(:not, sexp)
603
611
  def process_not(sexp, level)
604
- code = "!#{process sexp.shift, :expr}"
605
- code
612
+ with_temp do |tmp|
613
+ "(#{tmp} = #{process(sexp.shift, :expr)}, (#{tmp} === nil || #{tmp} === false))"
614
+ end
615
+ # code = "!#{process sexp.shift, :expr}"
616
+ # code
606
617
  end
607
618
 
608
619
  def process_block_pass(exp, level)
@@ -736,7 +747,7 @@ module Opal
736
747
  end
737
748
  end
738
749
 
739
- out.join ", \n#@indent"
750
+ out.join(", \n#@indent") + ', nil'
740
751
  end
741
752
 
742
753
  def handle_alias_native(sexp)
@@ -782,7 +793,7 @@ module Opal
782
793
 
783
794
  splat = arglist[1..-1].any? { |a| a.first == :splat }
784
795
 
785
- if Sexp === arglist.last and arglist.last.first == :block_pass
796
+ if Array === arglist.last and arglist.last.first == :block_pass
786
797
  block = process s(:js_tmp, process(arglist.pop, :expr)), :expr
787
798
  elsif iter
788
799
  block = iter
@@ -795,7 +806,7 @@ module Opal
795
806
  elsif splat and recv != [:self] and recv[0] != :lvar
796
807
  tmprecv = @scope.new_temp
797
808
  end
798
-
809
+
799
810
  args = ""
800
811
 
801
812
  recv_code = process recv, :recv
@@ -893,19 +904,33 @@ module Opal
893
904
  in_scope(:class) do
894
905
  @scope.name = name
895
906
  @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
896
- @scope.donates_methods = true
907
+
908
+ if Array === body.last
909
+ # A single statement will need a block
910
+ needs_block = body.last.first != :block
911
+ body.last.first == :block
912
+ last_body_statement = needs_block ? body.last : body.last.last
913
+
914
+ if last_body_statement and Array === last_body_statement
915
+ if [:defn, :defs].include? last_body_statement.first
916
+ body[-1] = s(:block, body[-1]) if needs_block
917
+ body.last << s(:nil)
918
+ end
919
+ end
920
+ end
921
+
922
+ body = returns(body)
897
923
  body = process body, :stmt
898
- code = @indent + @scope.to_vars + "\n\n#@indent" + body
899
- code += "\n#{@scope.to_donate_methods}"
924
+ code = "\n#{@scope.to_donate_methods}"
925
+ code += @indent + @scope.to_vars + "\n\n#@indent" + body
900
926
  end
901
927
  end
902
928
 
903
929
  spacer = "\n#{@indent}#{INDENT}"
904
930
  cls = "function #{name}() {};"
905
931
  boot = "#{name} = __klass(__base, __super, #{name.inspect}, #{name});"
906
- comment = "#{spacer}// line #{ sexp.line }, #{ @file }, class #{ name }"
907
932
 
908
- "(function(__base, __super){#{comment}#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base}, #{sup})"
933
+ "(function(__base, __super){#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base}, #{sup})"
909
934
  end
910
935
 
911
936
  # s(:sclass, recv, body)
@@ -948,7 +973,6 @@ module Opal
948
973
  in_scope(:module) do
949
974
  @scope.name = name
950
975
  @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
951
- @scope.donates_methods = true
952
976
  body = process body, :stmt
953
977
  code = @indent + @scope.to_vars + "\n\n#@indent" + body + "\n#@indent" + @scope.to_donate_methods
954
978
  end
@@ -957,9 +981,8 @@ module Opal
957
981
  spacer = "\n#{@indent}#{INDENT}"
958
982
  cls = "function #{name}() {};"
959
983
  boot = "#{name} = __module(__base, #{name.inspect}, #{name});"
960
- comment = "#{spacer}// line #{ sexp.line }, #{ @file }, module #{ name }"
961
984
 
962
- "(function(__base){#{comment}#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base})"
985
+ "(function(__base){#{spacer}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base})"
963
986
  end
964
987
 
965
988
  def process_undef(exp, level)
@@ -1008,7 +1031,7 @@ module Opal
1008
1031
  uses_super = nil
1009
1032
 
1010
1033
  # opt args if last arg is sexp
1011
- opt = args.pop if Sexp === args.last
1034
+ opt = args.pop if Array === args.last
1012
1035
 
1013
1036
  # block name &block
1014
1037
  if args.last.to_s.start_with? '&'
@@ -1071,18 +1094,10 @@ module Opal
1071
1094
 
1072
1095
  defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {\n#{code}\n#@indent}"
1073
1096
 
1074
- comment = "// line #{line}, #{@file}"
1075
-
1076
- if @scope.class_scope?
1077
- comment += ", #{ @scope.name }#{ recvr ? '.' : '#' }#{ mid }"
1078
- end
1079
-
1080
- comment += "\n#{@indent}"
1081
-
1082
1097
  if recvr
1083
1098
  if smethod
1084
1099
  @scope.smethods << "$#{mid}"
1085
- "#{ comment }#{ @scope.name }#{jsid} = #{defcode}"
1100
+ "#{ @scope.name }#{jsid} = #{defcode}"
1086
1101
  else
1087
1102
  "#{ recv }#{ jsid } = #{ defcode }"
1088
1103
  end
@@ -1092,7 +1107,7 @@ module Opal
1092
1107
  @scope.add_temp uses_super
1093
1108
  uses_super = "#{uses_super} = #{@scope.proto}#{jsid};\n#@indent"
1094
1109
  end
1095
- "#{ comment }#{uses_super}#{ @scope.proto }#{jsid} = #{defcode}"
1110
+ "#{uses_super}#{ @scope.proto }#{jsid} = #{defcode}"
1096
1111
  elsif @scope.type == :iter
1097
1112
  "def#{jsid} = #{defcode}"
1098
1113
  elsif @scope.type == :top
@@ -1195,8 +1210,34 @@ module Opal
1195
1210
 
1196
1211
  # s(:hash, key1, val1, key2, val2...)
1197
1212
  def process_hash(sexp, level)
1198
- @helpers[:hash] = true
1199
- "__hash(#{sexp.map { |p| process p, :expr }.join ', '})"
1213
+ keys = []
1214
+ vals = []
1215
+
1216
+ sexp.each_with_index do |obj, idx|
1217
+ if idx.even?
1218
+ keys << obj
1219
+ else
1220
+ vals << obj
1221
+ end
1222
+ end
1223
+
1224
+ if keys.all? { |k| [:lit, :str].include? k[0] }
1225
+ hash_obj = {}
1226
+ hash_keys = []
1227
+ keys.size.times do |i|
1228
+ k = process(keys[i], :expr)
1229
+ hash_keys << k unless hash_obj.include? k
1230
+ hash_obj[k] = process(vals[i], :expr)
1231
+ end
1232
+
1233
+ map = hash_keys.map { |k| "#{k}: #{hash_obj[k]}"}
1234
+
1235
+ @helpers[:hash2] = true
1236
+ "__hash2([#{hash_keys.join ', '}], {#{map.join(', ')}})"
1237
+ else
1238
+ @helpers[:hash] = true
1239
+ "__hash(#{sexp.map { |p| process p, :expr }.join ', '})"
1240
+ end
1200
1241
  end
1201
1242
 
1202
1243
  # s(:while, exp, block, true)
@@ -1862,7 +1903,7 @@ module Opal
1862
1903
  }.join ', '
1863
1904
  err = "true" if err.empty?
1864
1905
 
1865
- if Sexp === args.last and [:lasgn, :iasgn].include? args.last.first
1906
+ if Array === args.last and [:lasgn, :iasgn].include? args.last.first
1866
1907
  val = args.last
1867
1908
  val[2] = s(:js_tmp, "$err")
1868
1909
  val = process(val, :expr) + ";"
@@ -1895,4 +1936,4 @@ module Opal
1895
1936
  end
1896
1937
  end
1897
1938
  end
1898
- end
1939
+ end