opal 1.5.1 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +4 -0
  3. data/.github/workflows/build.yml +17 -3
  4. data/HACKING.md +23 -0
  5. data/README.md +3 -3
  6. data/UNRELEASED.md +47 -0
  7. data/benchmark/run.rb +1 -0
  8. data/docs/compiled_ruby.md +8 -0
  9. data/docs/compiler.md +1 -1
  10. data/docs/compiler_directives.md +1 -1
  11. data/docs/getting_started.md +17 -0
  12. data/docs/headless_chrome.md +1 -1
  13. data/docs/index.md +123 -0
  14. data/docs/jquery.md +5 -5
  15. data/docs/templates.md +37 -37
  16. data/docs/unsupported_features.md +0 -4
  17. data/lib/opal/builder.rb +59 -39
  18. data/lib/opal/builder_processors.rb +24 -0
  19. data/lib/opal/builder_scheduler/prefork.rb +262 -0
  20. data/lib/opal/builder_scheduler/sequential.rb +13 -0
  21. data/lib/opal/builder_scheduler.rb +29 -0
  22. data/lib/opal/cache/file_cache.rb +13 -2
  23. data/lib/opal/cli.rb +36 -19
  24. data/lib/opal/cli_options.rb +4 -0
  25. data/lib/opal/cli_runners/chrome.rb +17 -13
  26. data/lib/opal/cli_runners/chrome_cdp_interface.rb +19 -2
  27. data/lib/opal/cli_runners/compiler.rb +1 -1
  28. data/lib/opal/cli_runners/gjs.rb +3 -1
  29. data/lib/opal/cli_runners/mini_racer.rb +5 -3
  30. data/lib/opal/cli_runners/nodejs.rb +3 -3
  31. data/lib/opal/cli_runners/server.rb +13 -28
  32. data/lib/opal/cli_runners/system_runner.rb +5 -3
  33. data/lib/opal/cli_runners.rb +7 -6
  34. data/lib/opal/compiler.rb +25 -2
  35. data/lib/opal/config.rb +10 -0
  36. data/lib/opal/eof_content.rb +5 -2
  37. data/lib/opal/nodes/args/ensure_kwargs_are_kwargs.rb +2 -6
  38. data/lib/opal/nodes/args/extract_kwarg.rb +3 -4
  39. data/lib/opal/nodes/args/extract_kwargs.rb +3 -1
  40. data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -1
  41. data/lib/opal/nodes/args/extract_kwrestarg.rb +4 -1
  42. data/lib/opal/nodes/args/extract_optarg.rb +1 -1
  43. data/lib/opal/nodes/args/extract_post_arg.rb +1 -1
  44. data/lib/opal/nodes/args/extract_post_optarg.rb +1 -1
  45. data/lib/opal/nodes/args/extract_restarg.rb +2 -2
  46. data/lib/opal/nodes/args/initialize_iterarg.rb +1 -1
  47. data/lib/opal/nodes/args/initialize_shadowarg.rb +1 -1
  48. data/lib/opal/nodes/args/prepare_post_args.rb +4 -2
  49. data/lib/opal/nodes/base.rb +14 -3
  50. data/lib/opal/nodes/call.rb +13 -16
  51. data/lib/opal/nodes/class.rb +3 -1
  52. data/lib/opal/nodes/closure.rb +250 -0
  53. data/lib/opal/nodes/def.rb +7 -11
  54. data/lib/opal/nodes/definitions.rb +4 -2
  55. data/lib/opal/nodes/if.rb +12 -2
  56. data/lib/opal/nodes/iter.rb +11 -17
  57. data/lib/opal/nodes/logic.rb +15 -63
  58. data/lib/opal/nodes/module.rb +3 -1
  59. data/lib/opal/nodes/rescue.rb +23 -15
  60. data/lib/opal/nodes/scope.rb +7 -1
  61. data/lib/opal/nodes/top.rb +27 -4
  62. data/lib/opal/nodes/while.rb +42 -26
  63. data/lib/opal/nodes.rb +1 -0
  64. data/lib/opal/os.rb +59 -0
  65. data/lib/opal/rewriter.rb +2 -0
  66. data/lib/opal/rewriters/returnable_logic.rb +14 -0
  67. data/lib/opal/rewriters/thrower_finder.rb +90 -0
  68. data/lib/opal/simple_server.rb +12 -6
  69. data/lib/opal/source_map/file.rb +4 -3
  70. data/lib/opal/source_map/map.rb +9 -1
  71. data/lib/opal/util.rb +1 -1
  72. data/lib/opal/version.rb +1 -1
  73. data/opal/corelib/array.rb +68 -3
  74. data/opal/corelib/basic_object.rb +1 -0
  75. data/opal/corelib/comparable.rb +1 -1
  76. data/opal/corelib/complex.rb +1 -0
  77. data/opal/corelib/constants.rb +2 -2
  78. data/opal/corelib/enumerable.rb +4 -2
  79. data/opal/corelib/enumerator/chain.rb +4 -0
  80. data/opal/corelib/enumerator/generator.rb +5 -3
  81. data/opal/corelib/enumerator/lazy.rb +3 -1
  82. data/opal/corelib/enumerator/yielder.rb +2 -4
  83. data/opal/corelib/enumerator.rb +3 -1
  84. data/opal/corelib/error/errno.rb +3 -1
  85. data/opal/corelib/error.rb +13 -2
  86. data/opal/corelib/hash.rb +39 -1
  87. data/opal/corelib/io.rb +1 -1
  88. data/opal/corelib/kernel.rb +56 -5
  89. data/opal/corelib/module.rb +60 -4
  90. data/opal/corelib/proc.rb +8 -5
  91. data/opal/corelib/rational.rb +1 -0
  92. data/opal/corelib/regexp.rb +15 -1
  93. data/opal/corelib/runtime.js +307 -238
  94. data/opal/corelib/string/encoding.rb +0 -6
  95. data/opal/corelib/string.rb +28 -7
  96. data/opal/corelib/time.rb +5 -2
  97. data/opal/corelib/unsupported.rb +2 -14
  98. data/opal.gemspec +2 -2
  99. data/spec/filters/bugs/delegate.rb +11 -0
  100. data/spec/filters/bugs/kernel.rb +1 -3
  101. data/spec/filters/bugs/language.rb +3 -23
  102. data/spec/filters/bugs/method.rb +0 -1
  103. data/spec/filters/bugs/module.rb +0 -3
  104. data/spec/filters/bugs/proc.rb +0 -3
  105. data/spec/filters/bugs/set.rb +4 -16
  106. data/spec/filters/bugs/unboundmethod.rb +0 -2
  107. data/spec/filters/unsupported/array.rb +0 -58
  108. data/spec/filters/unsupported/freeze.rb +8 -192
  109. data/spec/filters/unsupported/hash.rb +0 -25
  110. data/spec/filters/unsupported/kernel.rb +0 -1
  111. data/spec/filters/unsupported/privacy.rb +17 -0
  112. data/spec/lib/builder_spec.rb +14 -0
  113. data/spec/lib/cli_runners/server_spec.rb +2 -3
  114. data/spec/lib/cli_spec.rb +15 -1
  115. data/spec/lib/compiler_spec.rb +1 -1
  116. data/spec/opal/core/language/DATA/characters_support_crlf_spec.rb +9 -0
  117. data/spec/opal/core/language/DATA/multiple___END___crlf_spec.rb +10 -0
  118. data/spec/opal/core/language/if_spec.rb +13 -0
  119. data/spec/opal/core/language/safe_navigator_spec.rb +10 -0
  120. data/spec/opal/core/module_spec.rb +8 -0
  121. data/spec/ruby_specs +2 -1
  122. data/stdlib/await.rb +44 -7
  123. data/stdlib/delegate.rb +427 -6
  124. data/stdlib/headless_chrome.rb +6 -2
  125. data/stdlib/nodejs/file.rb +2 -1
  126. data/stdlib/opal-parser.rb +1 -1
  127. data/stdlib/opal-platform.rb +1 -1
  128. data/stdlib/opal-replutils.rb +5 -3
  129. data/stdlib/promise.rb +3 -0
  130. data/stdlib/rbconfig.rb +4 -1
  131. data/stdlib/ruby2_keywords.rb +60 -0
  132. data/stdlib/set.rb +21 -0
  133. data/tasks/performance.rake +41 -35
  134. data/tasks/releasing.rake +1 -0
  135. data/tasks/testing/mspec_special_calls.rb +1 -0
  136. data/tasks/testing.rake +13 -12
  137. data/test/nodejs/test_await.rb +39 -1
  138. data/test/nodejs/test_file.rb +3 -2
  139. metadata +37 -22
  140. data/docs/faq.md +0 -17
  141. data/lib/opal/rewriters/break_finder.rb +0 -36
  142. data/spec/opal/core/kernel/freeze_spec.rb +0 -15
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
+ require 'json'
4
5
  require 'opal/version'
5
6
  require 'opal/nodes/scope'
6
7
 
@@ -32,7 +33,9 @@ module Opal
32
33
  in_scope do
33
34
  line '"use strict";' if compiler.use_strict?
34
35
 
35
- body_code = stmt(stmts)
36
+ body_code = in_closure(Closure::JS_FUNCTION | Closure::TOP) do
37
+ stmt(stmts)
38
+ end
36
39
  body_code = [body_code] unless body_code.is_a?(Array)
37
40
 
38
41
  if compiler.eval?
@@ -60,12 +63,18 @@ module Opal
60
63
  definition
61
64
  closing
62
65
  end
66
+
67
+ add_file_source_embed if compiler.enable_file_source_embed?
68
+ end
69
+
70
+ def module_name
71
+ Opal::Compiler.module_name(compiler.file).inspect
63
72
  end
64
73
 
65
74
  def definition
66
75
  if compiler.requirable?
67
- unshift "Opal.modules[#{Opal::Compiler.module_name(compiler.file).inspect}] = "
68
- elsif compiler.esm?
76
+ unshift "Opal.modules[#{module_name}] = "
77
+ elsif compiler.esm? && !compiler.no_export?
69
78
  unshift 'export default '
70
79
  end
71
80
  end
@@ -85,6 +94,14 @@ module Opal
85
94
  def closing
86
95
  if compiler.requirable?
87
96
  line "};\n"
97
+
98
+ if compiler.load?
99
+ # Opal.load normalizes the path, so that we can't
100
+ # require absolute paths from CLI. For other cases
101
+ # we can expect the module names to be normalized
102
+ # already.
103
+ line "Opal.load_normalized(#{module_name});"
104
+ end
88
105
  elsif compiler.eval?
89
106
  line "})(Opal, self);"
90
107
  else
@@ -109,7 +126,7 @@ module Opal
109
126
  end
110
127
 
111
128
  def add_used_helpers
112
- compiler.helpers.to_a.each { |h| add_temp "$#{h} = Opal.#{h}" }
129
+ compiler.helpers.to_a.reverse_each { |h| prepend_scope_temp "$#{h} = Opal.#{h}" }
113
130
  end
114
131
 
115
132
  def compile_method_stubs
@@ -131,6 +148,12 @@ module Opal
131
148
  def version_comment
132
149
  "/* Generated by Opal #{Opal::VERSION} */"
133
150
  end
151
+
152
+ def add_file_source_embed
153
+ filename = compiler.file
154
+ source = compiler.source
155
+ unshift "Opal.file_sources[#{filename.to_json}] = #{source.to_json};\n"
156
+ end
134
157
  end
135
158
  end
136
159
  end
@@ -12,20 +12,27 @@ module Opal
12
12
  def compile
13
13
  test_code = js_truthy(test)
14
14
 
15
- with_temp do |redo_var|
16
- compiler.in_while do
17
- while_loop[:closure] = true if wrap_in_closure?
18
- while_loop[:redo_var] = redo_var
15
+ @redo_var = scope.new_temp if uses_redo?
16
+
17
+ compiler.in_while do
18
+ while_loop[:closure] = true if wrap_in_closure?
19
+ while_loop[:redo_var] = @redo_var
20
+
21
+ in_closure(Closure::LOOP | Closure::JS_LOOP | (wrap_in_closure? ? Closure::JS_FUNCTION : 0)) do
22
+ in_closure(Closure::LOOP_INSIDE | Closure::JS_LOOP_INSIDE) do
23
+ line(indent { stmt(body) })
24
+ end
19
25
 
20
- body_code = indent { stmt(body) }
21
26
  if uses_redo?
22
- compile_with_redo(test_code, body_code, redo_var)
27
+ compile_with_redo(test_code)
23
28
  else
24
- compile_without_redo(test_code, body_code)
29
+ compile_without_redo(test_code)
25
30
  end
26
31
  end
27
32
  end
28
33
 
34
+ scope.queue_temp(@redo_var) if uses_redo?
35
+
29
36
  if wrap_in_closure?
30
37
  if scope.await_encountered
31
38
  wrap '(await (async function() {', '; return nil; })())'
@@ -37,26 +44,27 @@ module Opal
37
44
 
38
45
  private
39
46
 
40
- def compile_with_redo(test_code, body_code, redo_var)
41
- push "#{redo_var} = false; "
42
- compile_while(
43
- [redo_var, " || ", test_code],
44
- ["#{redo_var} = false;", body_code]
45
- )
47
+ def compile_with_redo(test_code)
48
+ compile_while(test_code, "#{@redo_var} = false;")
46
49
  end
47
50
 
48
- def compile_without_redo(test_code, body_code)
49
- compile_while([test_code], [body_code])
51
+ def compile_without_redo(test_code)
52
+ compile_while(test_code)
50
53
  end
51
54
 
52
- def compile_while(test_code, body_code)
53
- push while_open, *test_code, while_close
54
- indent { line(*body_code) }
55
+ def compile_while(test_code, redo_code = nil)
56
+ unshift redo_code if redo_code
57
+ unshift while_open, test_code, while_close
58
+ unshift redo_code if redo_code
55
59
  line '}'
56
60
  end
57
61
 
58
62
  def while_open
59
- 'while ('
63
+ if uses_redo?
64
+ redo_part = "#{@redo_var} || "
65
+ end
66
+
67
+ "while (#{redo_part}"
60
68
  end
61
69
 
62
70
  def while_close
@@ -64,7 +72,7 @@ module Opal
64
72
  end
65
73
 
66
74
  def uses_redo?
67
- while_loop[:use_redo]
75
+ @sexp.meta[:has_redo]
68
76
  end
69
77
 
70
78
  def wrap_in_closure?
@@ -78,7 +86,11 @@ module Opal
78
86
  private
79
87
 
80
88
  def while_open
81
- 'while (!('
89
+ if uses_redo?
90
+ redo_part = "#{@redo_var} || "
91
+ end
92
+
93
+ "while (#{redo_part}!("
82
94
  end
83
95
 
84
96
  def while_close
@@ -91,10 +103,10 @@ module Opal
91
103
 
92
104
  private
93
105
 
94
- def compile_while(test_code, body_code)
95
- push "do {"
96
- indent { line(*body_code) }
97
- line "} ", while_open, *test_code, while_close
106
+ def compile_while(test_code, redo_code = nil)
107
+ unshift redo_code if redo_code
108
+ unshift "do {"
109
+ line "} ", while_open, test_code, while_close
98
110
  end
99
111
 
100
112
  def while_close
@@ -108,7 +120,11 @@ module Opal
108
120
  private
109
121
 
110
122
  def while_open
111
- 'while(!('
123
+ if uses_redo?
124
+ redo_part = "#{@redo_var} || "
125
+ end
126
+
127
+ "while (#{redo_part}!("
112
128
  end
113
129
 
114
130
  def while_close
data/lib/opal/nodes.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'opal/nodes/closure'
3
4
  require 'opal/nodes/base'
4
5
  require 'opal/nodes/literal'
5
6
  require 'opal/nodes/variables'
data/lib/opal/os.rb ADDED
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Opal
4
+ module OS
5
+ module_function
6
+
7
+ def windows?
8
+ /bccwin|cygwin|djgpp|mingw|mswin|wince/.match?(RbConfig::CONFIG['host_os'])
9
+ end
10
+
11
+ def macos?
12
+ /darwin|mac os/.match?(RbConfig::CONFIG['host_os'])
13
+ end
14
+
15
+ def shellescape(str)
16
+ if windows?
17
+ '"' + str.gsub('"', '""') + '"'
18
+ else
19
+ str.shellescape
20
+ end
21
+ end
22
+
23
+ def env_sep
24
+ windows? ? ';' : ':'
25
+ end
26
+
27
+ def path_sep
28
+ windows? ? '\\' : '/'
29
+ end
30
+
31
+ def cmd_sep
32
+ windows? ? ' & ' : ' ; '
33
+ end
34
+
35
+ def dev_null
36
+ windows? ? 'NUL' : '/dev/null'
37
+ end
38
+
39
+ def bash_c(*commands)
40
+ cmd = if windows?
41
+ [
42
+ 'bundle',
43
+ 'exec',
44
+ 'cmd',
45
+ '/c',
46
+ ]
47
+ else
48
+ [
49
+ 'bundle',
50
+ 'exec',
51
+ 'bash',
52
+ '-c',
53
+ ]
54
+ end
55
+
56
+ cmd << commands.join(cmd_sep)
57
+ end
58
+ end
59
+ end
data/lib/opal/rewriter.rb CHANGED
@@ -15,6 +15,7 @@ require 'opal/rewriters/inline_args'
15
15
  require 'opal/rewriters/numblocks'
16
16
  require 'opal/rewriters/returnable_logic'
17
17
  require 'opal/rewriters/forward_args'
18
+ require 'opal/rewriters/thrower_finder'
18
19
 
19
20
  module Opal
20
21
  class Rewriter
@@ -66,6 +67,7 @@ module Opal
66
67
  use Rewriters::DumpArgs
67
68
  use Rewriters::MlhsArgs
68
69
  use Rewriters::InlineArgs
70
+ use Rewriters::ThrowerFinder
69
71
 
70
72
  def initialize(sexp)
71
73
  @sexp = sexp
@@ -21,6 +21,9 @@ module Opal
21
21
 
22
22
  def on_if(node)
23
23
  test, = *node.children
24
+
25
+ check_control_flow!(test)
26
+
24
27
  # The if_test metadata signifies that we don't care about the return value except if it's
25
28
  # truthy or falsy. And those tests will be carried out by the respective $truthy helper calls.
26
29
  test.meta[:if_test] = true if test
@@ -41,6 +44,8 @@ module Opal
41
44
  def on_or(node)
42
45
  lhs, rhs = *node.children
43
46
 
47
+ check_control_flow!(lhs)
48
+
44
49
  if node.meta[:if_test]
45
50
  # Let's forward the if_test to the lhs and rhs - since we don't care about the exact return
46
51
  # value of our or, we neither do care about a return value of our lhs or rhs.
@@ -58,6 +63,8 @@ module Opal
58
63
  def on_and(node)
59
64
  lhs, rhs = *node.children
60
65
 
66
+ check_control_flow!(lhs)
67
+
61
68
  if node.meta[:if_test]
62
69
  lhs.meta[:if_test] = rhs.meta[:if_test] = true
63
70
  out = process(node.updated(:if, [lhs, rhs, s(:false)]))
@@ -81,6 +88,13 @@ module Opal
81
88
 
82
89
  private
83
90
 
91
+ def check_control_flow!(node)
92
+ case node.type
93
+ when :break, :next, :redo, :retry, :return
94
+ error 'void value expression'
95
+ end
96
+ end
97
+
84
98
  def build_if_from_when(node, lhs, lhs_tmp, whens, els)
85
99
  first_when, *next_whens = *whens
86
100
 
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/EmptyLineBetweenDefs, Style/SingleLineMethods
4
+ module Opal
5
+ module Rewriters
6
+ # ThrowerFinder attempts to track the presence of throwers, like
7
+ # break, redo, so we can make an informed guess in the early
8
+ # compilation phase before traversing other nodes whether we
9
+ # want to track a closure. Tracking a closure is often a deoptimizing
10
+ # step, so we want to get that knowledge earlier.
11
+ class ThrowerFinder < Opal::Rewriters::Base
12
+ def initialize
13
+ @break_stack = []
14
+ @redo_stack = []
15
+ @retry_stack = []
16
+ @rescue_else_stack = []
17
+ end
18
+
19
+ def on_break(node)
20
+ tracking(:break, @break_stack)
21
+ super
22
+ end
23
+
24
+ def on_redo(node)
25
+ tracking(:redo, @redo_stack)
26
+ super
27
+ end
28
+
29
+ def on_retry(node)
30
+ tracking(:retry, @retry_stack)
31
+ super
32
+ end
33
+
34
+ def on_iter(node)
35
+ pushing([@break_stack, node]) { super }
36
+ end
37
+
38
+ def on_loop(node, &block)
39
+ pushing([@redo_stack, node], [@break_stack, nil], &block)
40
+ end
41
+
42
+ def on_for(node); on_loop(node) { super }; end
43
+ def on_while(node); on_loop(node) { super }; end
44
+ def on_while_post(node); on_loop(node) { super }; end
45
+ def on_until(node); on_loop(node) { super }; end
46
+ def on_until_post(node); on_loop(node) { super }; end
47
+
48
+ # ignore throwers inside defined
49
+ def on_defined(node)
50
+ pushing(
51
+ [@redo_stack, nil],
52
+ [@break_stack, nil],
53
+ [@retry_stack, nil]
54
+ ) { super }
55
+ end
56
+
57
+ # In Opal we handle rescue-else either in ensure or in
58
+ # rescue. If ensure is present, we handle it in ensure.
59
+ # Otherwise we handle it in rescue. ensure is always
60
+ # above a rescue. This logic is about tracking if a given
61
+ # ensure node should expect a rescue-else inside a
62
+ # rescue node.
63
+ def on_ensure(node)
64
+ pushing([@rescue_else_stack, node]) { super }
65
+ end
66
+
67
+ def on_rescue(node)
68
+ if node.children[1..-1].detect { |sexp| sexp && sexp.type != :resbody }
69
+ tracking(:rescue_else, @rescue_else_stack)
70
+ end
71
+
72
+ pushing([@rescue_else_stack, nil], [@retry_stack, node]) { super }
73
+ end
74
+
75
+ private
76
+
77
+ def pushing(*stacks)
78
+ stacks.each { |stack, node| stack.push(node) }
79
+ result = yield
80
+ stacks.map(&:first).each(&:pop)
81
+ result
82
+ end
83
+
84
+ def tracking(breaker, stack)
85
+ stack.last.meta[:"has_#{breaker}"] = true if stack.last
86
+ end
87
+ end
88
+ end
89
+ end
90
+ # rubocop:enable Layout/EmptyLineBetweenDefs, Style/SingleLineMethods
@@ -11,6 +11,8 @@ require 'opal/deprecations'
11
11
  #
12
12
  # @example (CLI)
13
13
  # rackup -ropal -ropal/simple_server -b 'Opal.append_path("app"); run Opal::SimpleServer.new'
14
+ # ... or use the Server runner ...
15
+ # opal -Rserver app.rb
14
16
  class Opal::SimpleServer
15
17
  require 'set'
16
18
  require 'erb'
@@ -54,13 +56,16 @@ class Opal::SimpleServer
54
56
  ]
55
57
  end
56
58
 
57
- def fetch_asset(path)
59
+ def builder(path)
58
60
  builder = Opal::Builder.new
59
61
  builder.build(path.gsub(/(\.(?:rb|js|opal))*\z/, ''))
62
+ end
63
+
64
+ def fetch_asset(path)
65
+ builder = self.builder(path)
60
66
  {
61
67
  data: builder.to_s,
62
- map: builder.source_map,
63
- source: builder.source_for(path),
68
+ map: builder.source_map
64
69
  }
65
70
  end
66
71
 
@@ -86,10 +91,11 @@ class Opal::SimpleServer
86
91
  <!doctype html>
87
92
  <html>
88
93
  <head>
89
- <meta charset="utf8">
90
- #{javascript_include_tag(main)}
94
+ <meta charset="utf-8">
91
95
  </head>
92
- <body></body>
96
+ <body>
97
+ #{javascript_include_tag(main)}
98
+ </body>
93
99
  </html>
94
100
  HTML
95
101
  end
@@ -51,7 +51,7 @@ class Opal::SourceMap::File
51
51
  # file: "out.js", # This is optional
52
52
  sourceRoot: source_root,
53
53
  sources: [file],
54
- sourcesContent: [source.force_encoding('UTF-8')],
54
+ sourcesContent: [source.encoding == Encoding::UTF_8 ? source : source.encode('UTF-8', undef: :replace)],
55
55
  names: names,
56
56
  mappings: Opal::SourceMap::VLQ.encode_mappings(relative_mappings),
57
57
  # x_com_opalrb_original_lines: source.count("\n"),
@@ -182,8 +182,9 @@ class Opal::SourceMap::File
182
182
  def fragments_by_line
183
183
  raw_mappings = [[]]
184
184
  fragments.flat_map do |fragment|
185
- fragment_code = fragment.code
186
- fragment_lines = fragment_code.split("\n", -1) # a negative limit won't suppress trailing null values
185
+ fragment_code = fragment.code
186
+ splitter = /\r/.match?(fragment_code) ? /\r?\n/ : "\n"
187
+ fragment_lines = fragment_code.split(splitter, -1) # a negative limit won't suppress trailing null values
187
188
  fragment_lines.each.with_index do |fragment_line, index|
188
189
  raw_segment = [fragment_line, fragment]
189
190
  if index.zero? && !fragment_line.size.zero?
@@ -9,7 +9,15 @@ module Opal::SourceMap::Map
9
9
  end
10
10
 
11
11
  def to_json
12
- to_h.to_json
12
+ map = to_h
13
+ map.to_json
14
+ rescue Encoding::UndefinedConversionError
15
+ map[:sections].each do |i|
16
+ i.to_json
17
+ rescue Encoding::UndefinedConversionError
18
+ map[:sections].delete(i)
19
+ end
20
+ map.to_json
13
21
  end
14
22
 
15
23
  def as_json(*)
data/lib/opal/util.rb CHANGED
@@ -15,7 +15,7 @@ module Opal
15
15
  # @param str [String] string to minify
16
16
  # @return [String]
17
17
  def uglify(source, mangle: false)
18
- sh "bin/yarn -s run terser -c #{'-m' if mangle}", data: source
18
+ sh "#{'ruby ' if Gem.win_platform?}bin/yarn -s run terser -c #{'-m' if mangle}", data: source
19
19
  end
20
20
 
21
21
  # Gzip code to check file size.
data/lib/opal/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  module Opal
4
4
  # WHEN RELEASING:
5
5
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
6
- VERSION = '1.5.1'
6
+ VERSION = '1.6.0.rc1'
7
7
  end