opal 0.9.4 → 0.10.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +2 -3
  4. data/.gitmodules +5 -2
  5. data/.jshintrc +1 -8
  6. data/.rspec +1 -1
  7. data/.travis.yml +15 -23
  8. data/CHANGELOG.md +511 -326
  9. data/CODE_OF_CONDUCT.md +13 -15
  10. data/CONTRIBUTING.md +26 -216
  11. data/Gemfile +20 -12
  12. data/Guardfile +2 -2
  13. data/HACKING.md +230 -0
  14. data/README.md +6 -7
  15. data/bin/opal-mspec +1 -1
  16. data/config.ru +2 -2
  17. data/docs/faq.md +1 -1
  18. data/docs/source_maps.md +1 -1
  19. data/lib/opal.rb +1 -0
  20. data/lib/opal/builder.rb +1 -1
  21. data/lib/opal/cli.rb +30 -28
  22. data/lib/opal/cli_options.rb +3 -0
  23. data/lib/opal/cli_runners.rb +14 -1
  24. data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
  25. data/lib/opal/cli_runners/nashorn.rb +2 -2
  26. data/lib/opal/cli_runners/nodejs.rb +2 -2
  27. data/lib/opal/cli_runners/phantom.js +24 -0
  28. data/lib/opal/cli_runners/phantomjs.rb +10 -10
  29. data/lib/opal/cli_runners/server.rb +3 -3
  30. data/lib/opal/compiler.rb +43 -4
  31. data/lib/opal/config.rb +3 -1
  32. data/lib/opal/errors.rb +13 -0
  33. data/lib/opal/fragment.rb +0 -13
  34. data/lib/opal/nodes.rb +10 -0
  35. data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
  36. data/lib/opal/nodes/args/kwarg.rb +29 -0
  37. data/lib/opal/nodes/args/kwoptarg.rb +29 -0
  38. data/lib/opal/nodes/args/kwrestarg.rb +39 -0
  39. data/lib/opal/nodes/args/mlhsarg.rb +79 -0
  40. data/lib/opal/nodes/args/normarg.rb +26 -0
  41. data/lib/opal/nodes/args/optarg.rb +27 -0
  42. data/lib/opal/nodes/args/post_args.rb +200 -0
  43. data/lib/opal/nodes/args/post_kwargs.rb +31 -0
  44. data/lib/opal/nodes/args/restarg.rb +33 -0
  45. data/lib/opal/nodes/base.rb +12 -0
  46. data/lib/opal/nodes/call.rb +92 -33
  47. data/lib/opal/nodes/def.rb +26 -169
  48. data/lib/opal/nodes/hash.rb +10 -4
  49. data/lib/opal/nodes/helpers.rb +6 -3
  50. data/lib/opal/nodes/inline_args.rb +61 -0
  51. data/lib/opal/nodes/iter.rb +73 -82
  52. data/lib/opal/nodes/logic.rb +12 -2
  53. data/lib/opal/nodes/masgn.rb +1 -2
  54. data/lib/opal/nodes/node_with_args.rb +141 -0
  55. data/lib/opal/nodes/rescue.rb +121 -43
  56. data/lib/opal/nodes/scope.rb +24 -5
  57. data/lib/opal/nodes/super.rb +122 -54
  58. data/lib/opal/nodes/top.rb +0 -12
  59. data/lib/opal/nodes/yield.rb +2 -13
  60. data/lib/opal/parser.rb +67 -39
  61. data/lib/opal/parser/grammar.rb +3319 -2961
  62. data/lib/opal/parser/grammar.y +234 -46
  63. data/lib/opal/parser/lexer.rb +105 -17
  64. data/lib/opal/parser/sexp.rb +4 -0
  65. data/lib/opal/paths.rb +4 -0
  66. data/lib/opal/regexp_anchors.rb +19 -1
  67. data/lib/opal/sprockets.rb +21 -18
  68. data/lib/opal/sprockets/environment.rb +0 -8
  69. data/lib/opal/sprockets/processor.rb +13 -16
  70. data/lib/opal/sprockets/server.rb +6 -12
  71. data/lib/opal/version.rb +1 -1
  72. data/opal.gemspec +1 -0
  73. data/opal/corelib/array.rb +209 -131
  74. data/opal/corelib/basic_object.rb +7 -3
  75. data/opal/corelib/class.rb +11 -17
  76. data/opal/corelib/constants.rb +2 -2
  77. data/opal/corelib/enumerable.rb +178 -355
  78. data/opal/corelib/enumerator.rb +3 -46
  79. data/opal/corelib/error.rb +2 -2
  80. data/opal/corelib/file.rb +13 -1
  81. data/opal/corelib/hash.rb +26 -56
  82. data/opal/corelib/helpers.rb +10 -0
  83. data/opal/corelib/kernel.rb +6 -3
  84. data/opal/corelib/module.rb +62 -31
  85. data/opal/corelib/number.rb +7 -16
  86. data/opal/corelib/proc.rb +24 -9
  87. data/opal/corelib/range.rb +4 -13
  88. data/opal/corelib/runtime.js +515 -378
  89. data/opal/corelib/string.rb +21 -49
  90. data/opal/corelib/struct.rb +50 -35
  91. data/opal/corelib/unsupported.rb +18 -30
  92. data/opal/opal.rb +0 -1
  93. data/opal/opal/mini.rb +1 -0
  94. data/spec/README.md +6 -4
  95. data/spec/filters/bugs/array.rb +0 -42
  96. data/spec/filters/bugs/basicobject.rb +0 -2
  97. data/spec/filters/bugs/bigdecimal.rb +160 -0
  98. data/spec/filters/bugs/class.rb +0 -5
  99. data/spec/filters/bugs/date.rb +1 -48
  100. data/spec/filters/bugs/enumerable.rb +4 -12
  101. data/spec/filters/bugs/enumerator.rb +0 -1
  102. data/spec/filters/bugs/exception.rb +4 -3
  103. data/spec/filters/bugs/float.rb +4 -2
  104. data/spec/filters/bugs/kernel.rb +25 -10
  105. data/spec/filters/bugs/language.rb +119 -68
  106. data/spec/filters/bugs/method.rb +135 -0
  107. data/spec/filters/bugs/module.rb +13 -28
  108. data/spec/filters/bugs/proc.rb +18 -8
  109. data/spec/filters/bugs/range.rb +0 -3
  110. data/spec/filters/bugs/rational.rb +4 -0
  111. data/spec/filters/bugs/regexp.rb +68 -36
  112. data/spec/filters/bugs/string.rb +1 -1
  113. data/spec/filters/bugs/struct.rb +0 -12
  114. data/spec/filters/bugs/time.rb +1 -0
  115. data/spec/filters/bugs/unboundmethod.rb +2 -1
  116. data/spec/filters/unsupported/freeze.rb +3 -1
  117. data/spec/filters/unsupported/language.rb +0 -7
  118. data/spec/filters/unsupported/privacy.rb +7 -6
  119. data/spec/filters/unsupported/string.rb +10 -0
  120. data/spec/filters/unsupported/struct.rb +3 -0
  121. data/spec/filters/unsupported/symbol.rb +9 -0
  122. data/spec/filters/unsupported/taint.rb +0 -3
  123. data/spec/filters/unsupported/thread.rb +1 -0
  124. data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
  125. data/spec/lib/cli_spec.rb +42 -1
  126. data/spec/lib/compiler/call_spec.rb +700 -0
  127. data/spec/lib/compiler_spec.rb +46 -28
  128. data/spec/lib/config_spec.rb +13 -0
  129. data/spec/lib/parser/call_spec.rb +18 -0
  130. data/spec/lib/parser/def_spec.rb +29 -0
  131. data/spec/lib/parser/iter_spec.rb +15 -15
  132. data/spec/lib/parser/lambda_spec.rb +153 -12
  133. data/spec/lib/parser/string_spec.rb +5 -0
  134. data/spec/lib/parser/undef_spec.rb +1 -1
  135. data/spec/lib/parser/variables_spec.rb +24 -0
  136. data/spec/lib/paths_spec.rb +12 -5
  137. data/spec/lib/spec_helper.rb +5 -0
  138. data/spec/lib/sprockets/processor_spec.rb +6 -5
  139. data/spec/lib/sprockets_spec.rb +8 -0
  140. data/spec/mspec-opal/formatters.rb +188 -0
  141. data/spec/mspec-opal/runner.rb +193 -0
  142. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  143. data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
  144. data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
  145. data/spec/opal/core/kernel/loop_spec.rb +1 -1
  146. data/spec/opal/core/kernel/raise_spec.rb +1 -1
  147. data/spec/opal/core/language/heredoc_spec.rb +42 -0
  148. data/spec/opal/core/language/rescue_spec.rb +18 -0
  149. data/spec/opal/core/language_spec.rb +22 -0
  150. data/spec/opal/core/module/const_defined_spec.rb +1 -2
  151. data/spec/opal/core/module/name_spec.rb +6 -0
  152. data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
  153. data/spec/opal/core/runtime/rescue_spec.rb +12 -2
  154. data/spec/opal/core/runtime/super_spec.rb +1 -0
  155. data/spec/opal/core/string_spec.rb +21 -0
  156. data/spec/opal/stdlib/js_spec.rb +1 -1
  157. data/spec/opal/stdlib/native/hash_spec.rb +7 -0
  158. data/spec/opal/stdlib/promise/always_spec.rb +24 -5
  159. data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
  160. data/spec/opal/stdlib/promise/then_spec.rb +13 -5
  161. data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
  162. data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
  163. data/spec/ruby_specs +122 -0
  164. data/spec/spec_helper.rb +3 -15
  165. data/stdlib/base64.rb +51 -121
  166. data/stdlib/bigdecimal.rb +231 -0
  167. data/stdlib/bigdecimal/bignumber.js.rb +11 -0
  168. data/stdlib/bigdecimal/kernel.rb +5 -0
  169. data/stdlib/date.rb +252 -10
  170. data/stdlib/native.rb +38 -38
  171. data/stdlib/nodejs/dir.rb +8 -6
  172. data/stdlib/nodejs/file.rb +28 -3
  173. data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
  174. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
  175. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
  176. data/stdlib/nodejs/require.rb +1 -1
  177. data/stdlib/nodejs/yaml.rb +3 -2
  178. data/stdlib/opal-parser.rb +7 -2
  179. data/stdlib/pathname.rb +23 -1
  180. data/stdlib/phantomjs.rb +10 -0
  181. data/stdlib/promise.rb +38 -23
  182. data/tasks/building.rake +3 -3
  183. data/tasks/testing.rake +27 -14
  184. data/tasks/testing/mspec_special_calls.rb +1 -1
  185. data/tasks/testing/sprockets-phantomjs.js +4 -0
  186. data/test/opal/test_keyword.rb +110 -110
  187. data/test/opal/unsupported_and_bugs.rb +30 -0
  188. data/vendored-minitest/minitest/assertions.rb +1 -1
  189. metadata +65 -15
  190. data/.spectator +0 -2
  191. data/.spectator-mspec +0 -3
  192. data/opal/corelib/array/inheritance.rb +0 -127
  193. data/spec/rubyspecs +0 -139
@@ -113,7 +113,9 @@ module Opal
113
113
  end
114
114
 
115
115
  def cmdarg_push(n)
116
- @cmdarg = (@cmdarg << 1) | (n & 1)
116
+ unless @lparen_arg_seen
117
+ @cmdarg = (@cmdarg << 1) | (n & 1)
118
+ end
117
119
  end
118
120
 
119
121
  def cmdarg_pop
@@ -263,6 +265,22 @@ module Opal
263
265
  scanner[1].to_i(16).chr
264
266
  elsif scan(/u([0-9a-zA-Z]{1,4})/)
265
267
  scanner[1].to_i(16).chr(Encoding::UTF_8)
268
+ elsif scan(/C-([a-zA-Z])/)
269
+ # Control character ?\C-z or ?\C-Z
270
+ # ?\C-a = "\u0001" = 1
271
+ (scanner[1].downcase.ord - 'a'.ord + '1'.to_i(16)).chr(Encoding::UTF_8)
272
+ elsif scan(/C-([0-9])/)
273
+ # Control character ?\C-0
274
+ # ?\C-0 = "\u0010"
275
+ (scanner[1].ord - '0'.ord + '10'.to_i(16)).chr(Encoding::UTF_8)
276
+ elsif scan(/M-\\C-([a-zA-Z])/)
277
+ # Meta control character ?\M-\C-z or ?\M-\C-Z
278
+ # ?\M-\C-z = "\x81"
279
+ (scanner[1].downcase.ord - 'a'.ord + '81'.to_i(16)).chr(Encoding::UTF_8)
280
+ elsif scan(/M-\\C-([0-9])/)
281
+ # Meta control character ?\M-\C-0
282
+ # ?\M-\C-0 = "\x90"
283
+ (scanner[1].ord - '0'.ord + '90'.to_i(16)).chr(Encoding::UTF_8)
266
284
  else
267
285
  # escaped char doesnt need escaping, so just return it
268
286
  scan(/./)
@@ -279,7 +297,7 @@ module Opal
279
297
 
280
298
  def here_document(str_parse)
281
299
  eos_regx = /[ \t]*#{Regexp.escape(str_parse[:term])}(\r*\n|$)/
282
- expand = true
300
+ expand = (str_parse[:func] & STR_FUNC_EXPAND) != 0
283
301
 
284
302
  # Don't escape single-quoted heredoc identifiers
285
303
  escape = str_parse[:func] != STR_SQUOTE
@@ -327,6 +345,15 @@ module Opal
327
345
  complete_str = str_buffer.join ''
328
346
  @line += complete_str.count("\n")
329
347
 
348
+ if str_parse[:squiggly_heredoc]
349
+ # "squiggly" heredoc should be post-processed.
350
+ # here we remove the indentation of the least-indented
351
+ # line from each line of the content
352
+ lines = complete_str.lines
353
+ min_indent = lines.map { |line| line.scan(/#{REGEXP_START}\s+/)[0].length }.min
354
+ complete_str = lines.map { |line| line[min_indent, line.length] }.join
355
+ end
356
+
330
357
  self.yylval = complete_str
331
358
  return :tSTRING_CONTENT
332
359
  end
@@ -402,6 +429,14 @@ module Opal
402
429
  return :tSTRING_DBEG
403
430
  else
404
431
  str_buffer << scanner.matched
432
+
433
+ # For qword without interpolation containing its :paren symbols
434
+ # like %w(()) ow %i{{}} we should mark our str_parse expression
435
+ # as nesting. As a result, #add_string_content will try to read 1 more
436
+ # closing ')' or '}' from the string
437
+ if qwords && scanner.matched.match(Regexp.new(Regexp.escape(str_parse[:paren])))
438
+ str_parse[:nesting] += 1
439
+ end
405
440
  end
406
441
 
407
442
  # causes error, so we will just collect it later on with other text
@@ -514,12 +549,34 @@ module Opal
514
549
  end
515
550
 
516
551
  def heredoc_identifier
517
- if scan(/(-?)(['"])?(\w+)\2?/)
518
- escape_method = (@scanner[2] == "'") ? STR_SQUOTE : STR_DQUOTE
519
- heredoc = @scanner[3]
552
+ starts_with_minus = !!scan(/-/) # optional heredoc beginning
553
+
554
+ squiggly_heredoc = !starts_with_minus && !!scan(/~/)
555
+
556
+ # Escaping character can be ' or " or can be blank
557
+ scan(/(['"]?)/)
558
+ escape_char = @scanner[0]
559
+
560
+ if escape_char != ''
561
+ # When heredoc identified starts with ' or "
562
+ # we should read until the same closing character appears
563
+ # again in the source
564
+ regexp = Regexp.new("([^#{escape_char}]+)")
565
+ else
566
+ # Otherwise we read all characters until whitespace found
567
+ regexp = /\w+/
568
+ end
569
+
570
+ if scan(regexp)
571
+ escape_method = (escape_char == "'") ? STR_SQUOTE : STR_DQUOTE
572
+ heredoc = @scanner[0]
520
573
 
521
574
  self.strterm = new_strterm(escape_method, heredoc, heredoc)
522
575
  self.strterm[:type] = :heredoc
576
+ self.strterm[:squiggly_heredoc] = squiggly_heredoc
577
+
578
+ # read closing ' or " character
579
+ scan(Regexp.new(escape_char)) if escape_char
523
580
 
524
581
  # if ruby code at end of line after heredoc, we have to store it to
525
582
  # parse after heredoc is finished parsing
@@ -629,6 +686,8 @@ module Opal
629
686
  @lex_state = :expr_end
630
687
  end
631
688
 
689
+ self.yylval = matched
690
+
632
691
  return matched =~ /#{REGEXP_START}[A-Z]/ ? :tCONSTANT : :tIDENTIFIER
633
692
  end
634
693
 
@@ -695,8 +754,13 @@ module Opal
695
754
  if scan(/\*\*\=/)
696
755
  return new_op_asgn('**')
697
756
  elsif scan(/\*\*/)
698
- self.set_arg_state
699
- return :tPOW
757
+ if [:expr_beg, :expr_mid].include? @lex_state
758
+ # kwsplat like **{ a: 1 }
759
+ return :tDSTAR
760
+ else
761
+ self.set_arg_state
762
+ return :tPOW
763
+ end
700
764
  elsif scan(/\*\=/)
701
765
  return new_op_asgn('*')
702
766
  else
@@ -835,7 +899,7 @@ module Opal
835
899
  self.set_arg_state
836
900
  return :tPIPE
837
901
 
838
- elsif scan(/\%[QqWwixrs]/)
902
+ elsif scan(/\%[QqWwIixrs]/)
839
903
  str_type = scanner.matched[1, 1]
840
904
  paren = term = scan(/./)
841
905
 
@@ -844,7 +908,8 @@ module Opal
844
908
  when '[' then term = ']'
845
909
  when '{' then term = '}'
846
910
  when '<' then term = '>'
847
- else paren = "\0"
911
+ else
912
+ paren = "\0"
848
913
  end
849
914
 
850
915
  token, func = case str_type
@@ -852,7 +917,7 @@ module Opal
852
917
  [:tSTRING_BEG, STR_DQUOTE]
853
918
  when 'q'
854
919
  [:tSTRING_BEG, STR_SQUOTE]
855
- when 'W'
920
+ when 'W', 'I'
856
921
  skip(/\s*/)
857
922
  [:tWORDS_BEG, STR_DWORD]
858
923
  when 'w', 'i'
@@ -893,15 +958,27 @@ module Opal
893
958
  return :tDIVIDE
894
959
 
895
960
  elsif scan(/\%/)
896
- if scan(/\=/)
961
+ if check(/\=/) && @lex_state != :expr_beg
962
+ scan(/\=/)
897
963
  return new_op_asgn('%')
898
964
  elsif check(/[^\s]/)
965
+
899
966
  if @lex_state == :expr_beg or
900
- (@lex_state == :expr_arg && @space_seen) or
967
+ @lex_state == :expr_arg && @space_seen or
901
968
  @lex_state == :expr_mid
902
- start_word = scan(/./)
903
- end_word = { '(' => ')', '[' => ']', '{' => '}', '<' => '>' }[start_word] || start_word
904
- self.strterm = new_strterm2(STR_DQUOTE, end_word, start_word)
969
+
970
+ paren = term = scan(/./)
971
+
972
+ case term
973
+ when '(' then term = ')'
974
+ when '[' then term = ']'
975
+ when '{' then term = '}'
976
+ when '<' then term = '>'
977
+ else
978
+ paren = "\0"
979
+ end
980
+
981
+ self.strterm = new_strterm2(STR_DQUOTE, term, paren)
905
982
  return :tSTRING_BEG
906
983
  end
907
984
  end
@@ -920,9 +997,12 @@ module Opal
920
997
 
921
998
  elsif scan(/\(/)
922
999
  result = scanner.matched
1000
+ @lparen_arg_seen = false
1001
+
923
1002
  if beg?
924
1003
  result = :tLPAREN
925
1004
  elsif @space_seen && arg?
1005
+ @lparen_arg_seen = true
926
1006
  result = :tLPAREN_ARG
927
1007
  else
928
1008
  result = :tLPAREN2
@@ -1185,6 +1265,9 @@ module Opal
1185
1265
  elsif scan(/\$\w+/)
1186
1266
  @lex_state = :expr_end
1187
1267
  return :tGVAR
1268
+ elsif scan(/\$-[0-9a-zA-Z]/)
1269
+ @lex_state = :expr_end
1270
+ return :tGVAR
1188
1271
  else
1189
1272
  raise "Bad gvar name: #{scanner.peek(5).inspect}"
1190
1273
  end
@@ -1214,7 +1297,12 @@ module Opal
1214
1297
  return :tLAMBEG
1215
1298
 
1216
1299
  elsif arg? or @lex_state == :expr_end
1217
- result = :tLCURLY
1300
+ if @lparen_arg_seen
1301
+ @lparen_arg_seen = false
1302
+ result = :tLBRACE_ARG
1303
+ else
1304
+ result = :tLCURLY
1305
+ end
1218
1306
  elsif @lex_state == :expr_endarg
1219
1307
  result = :LBRACE_ARG
1220
1308
  else
@@ -1240,7 +1328,7 @@ module Opal
1240
1328
  elsif check(/[0-9]/)
1241
1329
  return process_numeric
1242
1330
 
1243
- elsif scan(/(\w)+(\?|(\!(?!=)))?/)
1331
+ elsif scan(IDENTIFIER_REGEXP)
1244
1332
  return process_identifier scanner.matched, cmd_start
1245
1333
  end
1246
1334
 
@@ -28,6 +28,10 @@ module Opal
28
28
  @array[1..-1]
29
29
  end
30
30
 
31
+ def meta
32
+ @meta ||= {}
33
+ end
34
+
31
35
  def method_missing(sym, *args, &block)
32
36
  @array.send sym, *args, &block
33
37
  end
data/lib/opal/paths.rb CHANGED
@@ -33,6 +33,8 @@ module Opal
33
33
  # @param gem_name [String] the name of the gem
34
34
  # @param include_dependencies [Boolean] whether or not to add recursively
35
35
  # the gem's dependencies
36
+ # @raise [Opal::GemNotFound]
37
+ # if gem or any of its runtime dependencies not found
36
38
  def use_gem(gem_name, include_dependencies = true)
37
39
  append_paths(*require_paths_for_gem(gem_name, include_dependencies))
38
40
  end
@@ -41,7 +43,9 @@ module Opal
41
43
 
42
44
  def require_paths_for_gem(gem_name, include_dependencies)
43
45
  paths = []
46
+
44
47
  spec = Gem::Specification.find_by_name(gem_name)
48
+ raise GemNotFound, gem_name unless spec
45
49
 
46
50
  spec.runtime_dependencies.each do |dependency|
47
51
  paths += require_paths_for_gem(dependency.name, include_dependencies)
@@ -1,5 +1,23 @@
1
1
  module Opal
2
2
  REGEXP_START = RUBY_ENGINE == 'opal' ? '^' : '\A'.freeze
3
- REGEXP_END = RUBY_ENGINE == 'opal' ? '$' : '\z'.freeze
3
+ REGEXP_END = RUBY_ENGINE == 'opal' ? '$' : '\z'.freeze
4
+
5
+ # Unicode characters in ranges
6
+ # \u0001 - \u0020 (blank unicode characters + space)
7
+ # \u0022 - \u002F ("#$%&'()*+,-./ chars)
8
+ # \u003A - \u003E (:;<=> chars)
9
+ # \u0040 (@ char)
10
+ # \u005B - \u005E ([\]^ chars)
11
+ # \u0060 (` char)
12
+ # \u007B - \u007F ({|}~ chars})
13
+ # are not allowed to be used in identifier in any form
14
+ # This regexp contains a common rule for filtering Ruby identifiers
15
+ FORBIDDEN_IDENTIFIER_CHARS = "\\u0001-\\u0020\\u0022-\\u002F\\u003A-\\u003E\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
16
+ IDENTIFIER_REGEXP = Regexp.new("[^#{FORBIDDEN_IDENTIFIER_CHARS}]+")
17
+
18
+ # For constants rules are pretty much the same, but ':' is allowed and '?!' are not.
19
+ # Plus it may start with a '::' which indicates that the constant comes from toplevel.
20
+ FORBIDDEN_CONST_NAME_CHARS = "\\u0001-\\u0020\\u0021-\\u002F\\u003B-\\u003F\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
21
+ CONST_NAME_REGEXP = Regexp.new("#{REGEXP_START}(::)?[A-Z][^#{FORBIDDEN_CONST_NAME_CHARS}]*#{REGEXP_END}")
4
22
  end
5
23
 
@@ -4,25 +4,25 @@ require 'opal/sprockets/server'
4
4
 
5
5
  module Opal
6
6
  module Sprockets
7
- # Public: Bootstraps modules loaded by sprockets on `Opal.modules` marking any
8
- # non-Opal asset as already loaded.
7
+ # Bootstraps modules loaded by sprockets on `Opal.modules` marking any
8
+ # non-Opal asset as already loaded.
9
9
  #
10
- # name - The name of the main asset to be loaded (with or without ext)
11
- # sprockets - A Sprockets::Environment instance
12
- #
13
- # Example
10
+ # @example
14
11
  #
15
12
  # Opal::Sprockets.load_asset(Rails.application.assets, 'application')
16
13
  #
17
- # Will output the following JavaScript:
14
+ # @example Will output the following JavaScript:
18
15
  #
19
16
  # if (typeof(Opal) !== 'undefined') {
20
- # Opal.mark_as_loaded("opal");
21
- # Opal.mark_as_loaded("jquery.self");
17
+ # Opal.loaded("opal");
18
+ # Opal.loaded("jquery.self");
22
19
  # Opal.load("application");
23
20
  # }
24
21
  #
25
- # Returns a String containing JavaScript code.
22
+ # @param name [String] The logical name of the main asset to be loaded (without extension)
23
+ # @param sprockets [Sprockets::Environment]
24
+ #
25
+ # @return [String] JavaScript code
26
26
  def self.load_asset(name, sprockets)
27
27
  asset = sprockets[name.sub(/(\.(js|rb|opal))*#{REGEXP_END}/, '.js')]
28
28
  return '' if asset.nil?
@@ -35,7 +35,7 @@ module Opal
35
35
  path_extnames = -> path { File.basename(path).scan(/\.[^.]+/) }
36
36
  mark_loaded = -> paths { "Opal.loaded([#{paths.map(&:inspect).join(',')}]);" }
37
37
  processed_by_opal = -> asset { (path_extnames[asset.pathname] & opal_extnames).any? }
38
- stubbed_files = ::Opal::Processor.stubbed_files
38
+ stubbed_files = ::Opal::Config.stubbed_files
39
39
 
40
40
  non_opal_assets = ([asset]+asset.dependencies)
41
41
  .select { |asset| not(processed_by_opal[asset]) }
@@ -54,20 +54,23 @@ module Opal
54
54
  "}"
55
55
  end
56
56
 
57
- # Public: Generate a `<script>` tag for Opal assets.
57
+ # Generate a `<script>` tag for Opal assets.
58
58
  #
59
- # name - The name of the asset to be loaded
60
- # options - (default: {}):
61
- # :sprockets - A Sprockets::Environment instance
62
- # :prefix - The prefix String at which is mounted Sprockets
63
- # :debug - Wether to enable debug mode along with sourcemaps support
59
+ # @param [String] name The logical name of the asset to be loaded (without extension)
60
+ # @param [Hash] options The options about sprockets
61
+ # @option options [Sprockets::Environment] :sprockets The sprockets instance
62
+ # @option options [String] :prefix The prefix String at which is mounted Sprockets, e.g. '/assets'
63
+ # @option options [Boolean] :debug Wether to enable debug mode along with sourcemaps support
64
64
  #
65
- # Returns a string of HTML code containing `<script>` tags.
65
+ # @return a string of HTML code containing `<script>` tags.
66
66
  def self.javascript_include_tag(name, options = {})
67
67
  sprockets = options.fetch(:sprockets)
68
68
  prefix = options.fetch(:prefix)
69
69
  debug = options.fetch(:debug)
70
70
 
71
+ # Avoid double slashes
72
+ prefix = prefix.chop if prefix.end_with? '/'
73
+
71
74
  asset = sprockets[name]
72
75
  raise "Cannot find asset: #{name}" if asset.nil?
73
76
  scripts = []
@@ -3,16 +3,8 @@ require 'opal/sprockets/processor'
3
3
  require 'opal/sprockets/erb'
4
4
 
5
5
  module Opal
6
- # @deprecated
7
- def self.process asset
8
- Environment.new[asset].to_s
9
- end
10
-
11
- # @deprecated
12
6
  class Environment < ::Sprockets::Environment
13
7
  def initialize *args
14
- warn "WARNING: Opal::Sprockets::Environment is deprecated. "\
15
- "Please use Opal::Server directly or append Opal.paths to the environment manually."
16
8
  super
17
9
  append_opal_paths
18
10
  end
@@ -12,13 +12,6 @@ module Opal
12
12
  # extensions) available to any sprockets based server. Processor will then
13
13
  # get passed any ruby source file to build.
14
14
  class Processor < TiltTemplate
15
- # Deprecated: Support legacy accessors to default options,
16
- # now moved to Opal::Config
17
- Opal::Config.default_config.keys.each do |config_option|
18
- define_singleton_method(config_option) { Opal::Config.config[config_option] }
19
- define_singleton_method("#{config_option}=") { |value| Opal::Config.config[config_option] = value }
20
- end
21
-
22
15
  @@cache_key = nil
23
16
  def self.cache_key
24
17
  @@cache_key ||= ['Opal', Opal::VERSION, Opal::Config.config].to_json.freeze
@@ -100,7 +93,7 @@ module Opal
100
93
  required_tree = dirname.join(file, '..', required_tree)
101
94
 
102
95
  unless required_tree.directory?
103
- raise ArgumentError, "require_tree argument must be a directory: #{[original_required_tree, required_tree].inspect}"
96
+ raise ArgumentError, "require_tree argument must be a directory: #{{source: original_required_tree, pathname: required_tree}.inspect}"
104
97
  end
105
98
 
106
99
  context.depend_on required_tree.to_s
@@ -125,21 +118,25 @@ module Opal
125
118
  end
126
119
  end
127
120
 
128
- # Deprecated: Moved to Opal::Sprockets.load_asset(sprockets, name)
129
- def self.load_asset_code(sprockets, name)
130
- ::Opal::Sprockets.load_asset(name, sprockets)
131
- end
132
-
121
+ # @deprecated
133
122
  def self.stubbed_files
134
- @stubbed_files ||= Set.new
123
+ warn "Deprecated: use `::Opal::Config.stubbed_files` instead"
124
+ puts caller(5)
125
+ ::Opal::Config.stubbed_files
135
126
  end
136
127
 
128
+ # @deprecated
137
129
  def self.stub_file(name)
138
- stubbed_files << name.to_s
130
+ warn "Deprecated: use `::Opal::Config.stubbed_files << #{name.inspect}.to_s` instead"
131
+ puts caller(5)
132
+ ::Opal::Config.stubbed_files << name.to_s
139
133
  end
140
134
 
135
+
136
+ private
137
+
141
138
  def stubbed_files
142
- self.class.stubbed_files
139
+ ::Opal::Config.stubbed_files
143
140
  end
144
141
  end
145
142
  end
@@ -13,15 +13,7 @@ module Opal
13
13
  attr_accessor :debug, :use_index, :index_path, :main, :public_root,
14
14
  :public_urls, :sprockets, :prefix
15
15
 
16
- def initialize debug_or_options = {}
17
- unless Hash === debug_or_options
18
- warn "passing a boolean to control debug is deprecated.\n"+
19
- "Please pass an Hash instead: Server.new(debug: true)"
20
- options = {:debug => debug_or_options}
21
- else
22
- options = debug_or_options
23
- end
24
-
16
+ def initialize options = {}
25
17
  @use_index = true
26
18
  @public_root = nil
27
19
  @public_urls = ['/']
@@ -41,11 +33,11 @@ module Opal
41
33
  end
42
34
 
43
35
  def source_map=(enabled)
44
- Opal::Processor.source_map_enabled = enabled
36
+ Opal::Config.source_map_enabled = enabled
45
37
  end
46
38
 
47
39
  def source_map_enabled
48
- Opal::Processor.source_map_enabled
40
+ Opal::Config.source_map_enabled
49
41
  end
50
42
 
51
43
  def append_path path
@@ -117,7 +109,9 @@ module Opal
117
109
  def javascript_include_tag name
118
110
  sprockets = @server.sprockets
119
111
  prefix = @server.prefix
120
- ::Opal::Sprockets.javascript_include_tag(name, sprockets: @server.sprockets, prefix: @server.prefix, debug: @server.debug)
112
+ debug = @server.debug
113
+
114
+ ::Opal::Sprockets.javascript_include_tag(name, sprockets: sprockets, prefix: prefix, debug: debug)
121
115
  end
122
116
 
123
117
  def source