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
data/README.md CHANGED
@@ -121,17 +121,16 @@ Just open this page and check the JavaScript console.
121
121
  production and should only be used as a quick way to getting you hands
122
122
  on opal
123
123
 
124
-
125
124
  ## Running tests
126
125
 
127
- First, install dependencies:
126
+ The Ruby Spec Suite related repos must be cloned as git submodules:
128
127
 
129
- $ bundle install
130
- $ npm install -g jshint
128
+ $ git submodule update --init
131
129
 
132
- RubySpec related repos must be cloned as git submodules:
130
+ Then, install dependencies:
133
131
 
134
- $ git submodule update --init
132
+ $ bundle install
133
+ $ npm install -g jshint
135
134
 
136
135
  The test suite can be run using (requires [phantomjs][]):
137
136
 
@@ -232,5 +231,5 @@ THE SOFTWARE.
232
231
 
233
232
 
234
233
  [phantomjs]: http://phantomjs.org
235
- [MSpec]: https://github.com/rubyspec/mspec#readme
234
+ [MSpec]: https://github.com/ruby/mspec#readme
236
235
  [RSpec]: https://github.com/rspec/rspec#readme
data/bin/opal-mspec CHANGED
@@ -7,4 +7,4 @@ pattern = %Q{MSPEC_PATTERN="{#{specs.join(',')}}"} if specs.any?
7
7
  command = [pattern, 'rake mspec'].compact.join(' ')
8
8
  exec command
9
9
 
10
- # RUBYOPT="-rbundler/setup -rmspec/opal/special_calls" bundle exec mspec run -t opal -pspec/rubyspec/spec_helper spec/rubyspec/core/true/*
10
+ # RUBYOPT="-rbundler/setup -rmspec/opal/special_calls" bundle exec mspec run -t opal -pspec/ruby/spec_helper spec/ruby/core/true/*
data/config.ru CHANGED
@@ -3,8 +3,8 @@ Bundler.require
3
3
 
4
4
  require 'mspec/opal/rake_task'
5
5
 
6
- ::Opal::Processor.arity_check_enabled = true
7
- ::Opal::Processor.dynamic_require_severity = :error
6
+ ::Opal::Config.arity_check_enabled = true
7
+ ::Opal::Config.dynamic_require_severity = :error
8
8
 
9
9
  use Rack::ShowExceptions
10
10
  use Rack::ShowStatus
data/docs/faq.md CHANGED
@@ -6,7 +6,7 @@ To try and keep ruby relevant in a world where client-side apps are making javas
6
6
 
7
7
  ### How compatible is Opal?
8
8
 
9
- We run opal against [rubyspec](https://github.com/rubyspec/rubyspec) as our primary testing setup. We try to make Opal as compatible as possible, whilst also taking into account restrictions of JavaScript when applicable. Opal supports the majority of ruby syntax features, as well as a very large part of the corelib implementation. We support method\_missing, modules, classes, instance\_exec, blocks, procs and lots lots more. Opal can compile and run Rspec unmodified, as well as self hosting the compiler at runtime.
9
+ We run opal against the [ruby spec](https://github.com/ruby/spec) as our primary testing setup. We try to make Opal as compatible as possible, whilst also taking into account restrictions of JavaScript when applicable. Opal supports the majority of ruby syntax features, as well as a very large part of the corelib implementation. We support method\_missing, modules, classes, instance\_exec, blocks, procs and lots lots more. Opal can compile and run Rspec unmodified, as well as self hosting the compiler at runtime.
10
10
 
11
11
  ### What version of ruby does Opal target?
12
12
 
data/docs/source_maps.md CHANGED
@@ -10,7 +10,7 @@ NOTE: Currently on `master` branch sourcemaps are work-in-progress and probably
10
10
  To enable sourcemaps in the Sprockets processor you need to turn on the relative flag:
11
11
 
12
12
  ```ruby
13
- Opal::Processor.source_map_enabled = true # default
13
+ Opal::Config.source_map_enabled = true # default
14
14
  ```
15
15
 
16
16
 
data/lib/opal.rb CHANGED
@@ -4,6 +4,7 @@ require 'opal/erb'
4
4
  require 'opal/sprockets'
5
5
  require 'opal/paths'
6
6
  require 'opal/version'
7
+ require 'opal/errors'
7
8
 
8
9
  # Opal is a ruby to javascript compiler, with a runtime for running
9
10
  # in any JavaScript environment.
data/lib/opal/builder.rb CHANGED
@@ -119,7 +119,7 @@ module Opal
119
119
  end
120
120
 
121
121
  def process_require(filename, options)
122
- filename.gsub!(/\.(rb|js|opal)#{REGEXP_END}/, '')
122
+ filename = filename.gsub(/\.(rb|js|opal)#{REGEXP_END}/, '')
123
123
  return if prerequired.include?(filename)
124
124
  return if already_processed.include?(filename)
125
125
  already_processed << filename
data/lib/opal/cli.rb CHANGED
@@ -7,7 +7,7 @@ module Opal
7
7
  class CLI
8
8
  attr_reader :options, :file, :compiler_options, :evals, :load_paths, :argv,
9
9
  :output, :requires, :gems, :stubs, :verbose, :port, :preload,
10
- :filename, :debug, :no_exit
10
+ :filename, :debug, :no_exit, :lib_only
11
11
 
12
12
  def compile?
13
13
  @compile
@@ -32,22 +32,23 @@ module Opal
32
32
  @runner_type = options.delete(:runner) || :nodejs
33
33
  @port = options.delete(:port) || 3000
34
34
 
35
- @options = options
36
- @compile = !!options.delete(:compile)
37
- @sexp = options.delete(:sexp)
38
- @file = options.delete(:file)
39
- @no_exit = options.delete(:no_exit)
40
- @argv = options.delete(:argv) || []
41
- @evals = options.delete(:evals) || []
42
- @requires = options.delete(:requires) || []
43
- @load_paths = options.delete(:load_paths) || []
44
- @gems = options.delete(:gems) || []
45
- @stubs = options.delete(:stubs) || []
46
- @preload = options.delete(:preload) || []
47
- @output = options.delete(:output) || self.class.stdout || $stdout
48
- @verbose = options.fetch(:verbose, false); options.delete(:verbose)
49
- @debug = options.fetch(:debug, false); options.delete(:debug)
50
- @filename = options.fetch(:filename) { @file && @file.path }; options.delete(:filename)
35
+ @options = options
36
+ @compile = !!options.delete(:compile)
37
+ @sexp = options.delete(:sexp)
38
+ @file = options.delete(:file)
39
+ @no_exit = options.delete(:no_exit)
40
+ @lib_only = options.delete(:lib_only)
41
+ @argv = options.delete(:argv) || []
42
+ @evals = options.delete(:evals) || []
43
+ @requires = options.delete(:requires) || []
44
+ @load_paths = options.delete(:load_paths) || []
45
+ @gems = options.delete(:gems) || []
46
+ @stubs = options.delete(:stubs) || []
47
+ @preload = options.delete(:preload) || []
48
+ @output = options.delete(:output) || self.class.stdout || $stdout
49
+ @verbose = options.fetch(:verbose, false); options.delete(:verbose)
50
+ @debug = options.fetch(:debug, false); options.delete(:debug)
51
+ @filename = options.fetch(:filename) { @file && @file.path }; options.delete(:filename)
51
52
  @skip_opal_require = options.delete(:skip_opal_require)
52
53
  @compiler_options = Hash[
53
54
  *compiler_option_names.map do |option|
@@ -58,7 +59,8 @@ module Opal
58
59
  end.compact.flatten
59
60
  ]
60
61
 
61
- raise ArgumentError, "no runnable code provided (evals or file)" if @evals.empty? and @file.nil?
62
+ raise ArgumentError, "no runnable code provided (evals or file)" if @evals.empty? and @file.nil? and not(@lib_only)
63
+ raise ArgumentError, "can't accept evals or file in `library only` mode" if (@evals.any? or @file) and @lib_only
62
64
  raise ArgumentError, "unknown options: #{options.inspect}" unless @options.empty?
63
65
  end
64
66
 
@@ -71,14 +73,12 @@ module Opal
71
73
  end
72
74
 
73
75
  def runner
74
- @runner ||= case @runner_type
75
- when :server; CliRunners::Server.new(output, port)
76
- when :nodejs; CliRunners::Nodejs.new(output)
77
- when :phantomjs; CliRunners::Phantomjs.new(output)
78
- when :applescript; CliRunners::AppleScript.new(output)
79
- when :nashorn; CliRunners::Nashorn.new(output)
80
- else raise ArgumentError, @runner_type.inspect
81
- end
76
+ @runner ||= begin
77
+ const_name = @runner_type.to_s.capitalize
78
+ CliRunners.const_defined?(const_name) or
79
+ raise ArgumentError, "unknown runner: #{@runner_type.inspect}"
80
+ CliRunners.const_get(const_name).new(output: output, port: port)
81
+ end
82
82
  end
83
83
 
84
84
  def run_code
@@ -106,8 +106,10 @@ module Opal
106
106
  builder.build(local_require)
107
107
  end
108
108
 
109
- evals_or_file do |contents, filename|
110
- builder.build_str(contents, filename)
109
+ unless lib_only
110
+ evals_or_file do |contents, filename|
111
+ builder.build_str(contents, filename)
112
+ end
111
113
  end
112
114
 
113
115
  builder.build_str 'Kernel.exit', '(exit)' unless no_exit
@@ -97,6 +97,9 @@ module Opal
97
97
  options[:no_exit] = true
98
98
  end
99
99
 
100
+ on('-L', '--library', 'Generate only the code of the library. Omit [programfile] and [-e]') do |no_exit|
101
+ options[:lib_only] = true
102
+ end
100
103
 
101
104
  section 'Compilation Options:'
102
105
 
@@ -1,11 +1,24 @@
1
1
  module Opal
2
+ # `Opal::CliRunners` is the namespace in which JavaScript runners can be
3
+ # defined for use by `Opal::CLI`. The API for classes defined under
4
+ # `CliRunners` is the following.
5
+ #
6
+ # - The #initialize method takes an `Hash` containing an `output:` object.
7
+ # Additional keys can be safely ignored and can be specific to a particular
8
+ # runner, e.g. the `CliRunners::Server` runner will accepts a `port:`
9
+ # option.
10
+ # - The runner instance will then be called via `#run(compiled_source, argv)`:
11
+ # - `compiled_source` is a string of JavaScript code
12
+ # - `argv` is the arguments vector coming from the CLI that is being
13
+ # forwarded to the program
14
+ #
2
15
  module CliRunners
3
16
  class RunnerError < StandardError
4
17
  end
5
18
  end
6
19
  end
7
20
 
8
- require 'opal/cli_runners/apple_script'
21
+ require 'opal/cli_runners/applescript'
9
22
  require 'opal/cli_runners/phantomjs'
10
23
  require 'opal/cli_runners/nodejs'
11
24
  require 'opal/cli_runners/server'
@@ -2,13 +2,13 @@ require 'opal/cli_runners'
2
2
 
3
3
  module Opal
4
4
  module CliRunners
5
- class AppleScript
6
- def initialize(output)
5
+ class Applescript
6
+ def initialize(options)
7
7
  unless system('which osalang > /dev/null')
8
8
  raise MissingJavaScriptSupport, 'JavaScript Automation is only supported by OS X Yosemite and above.'
9
9
  end
10
10
 
11
- @output ||= output
11
+ @output = options.fetch(:output, $stdout)
12
12
  end
13
13
  attr_reader :output, :exit_status
14
14
 
@@ -4,8 +4,8 @@ require 'opal/paths'
4
4
  module Opal
5
5
  module CliRunners
6
6
  class Nashorn
7
- def initialize(output)
8
- @output ||= output
7
+ def initialize(options)
8
+ @output = options.fetch(:output, $stdout)
9
9
  end
10
10
  attr_reader :output, :exit_status
11
11
 
@@ -4,8 +4,8 @@ require 'opal/paths'
4
4
  module Opal
5
5
  module CliRunners
6
6
  class Nodejs
7
- def initialize(output)
8
- @output ||= output
7
+ def initialize(options)
8
+ @output = options.fetch(:output, $stdout)
9
9
  end
10
10
  attr_reader :output, :exit_status
11
11
 
@@ -28,11 +28,35 @@ page.onCallback = function(data) {
28
28
  case 'stderr':
29
29
  system.stderr.write(data[1] || '');
30
30
  break;
31
+ case 'env':
32
+ return JSON.stringify(system.env);
33
+ case 'argv':
34
+ return JSON.stringify(system.args.slice(1));
31
35
  default:
32
36
  console.error('Unknown callback data: ', data);
33
37
  }
34
38
  };
35
39
 
40
+ page.onError = function(msg, trace) {
41
+ trace = (trace && trace.length) ? trace : [];
42
+
43
+ var format_trace = function(trace) {
44
+ var file = trace.file || trace.sourceURL,
45
+ line = trace.line,
46
+ method = trace['function'];
47
+ method = method ? "`"+method+"'" : '~unknown~';
48
+ return file+': '+line+':in '+method;
49
+ };
50
+
51
+ var msgStack = [format_trace(trace[0])+': '+msg];
52
+
53
+ trace.slice(1).forEach(function(t) {
54
+ msgStack.push(" from "+format_trace(t));
55
+ });
56
+
57
+ system.stderr.write(msgStack.join('\n')+'\n');
58
+ phantom_exit(1);
59
+ };
36
60
 
37
61
  page.onInitialized = function() {
38
62
  page.evaluate('function(code) {window.eval(code)}', opal_code)
@@ -3,25 +3,25 @@ require 'shellwords'
3
3
  module Opal
4
4
  module CliRunners
5
5
  class Phantomjs
6
- def initialize(output = $stdout)
7
- @output = output
6
+ SCRIPT_PATH = File.expand_path('../phantom.js', __FILE__)
7
+
8
+ def initialize(options)
9
+ @output = options.fetch(:output, $stdout)
8
10
  end
9
11
  attr_reader :output, :exit_status
10
12
 
11
13
  def run(code, argv)
12
- unless argv.empty?
13
- raise ArgumentError, 'Program arguments are not supported on the PhantomJS runner'
14
- end
14
+ command = [
15
+ 'phantomjs',
16
+ SCRIPT_PATH.shellescape,
17
+ *argv.map(&:shellescape)
18
+ ].join(' ')
15
19
 
16
20
  phantomjs = IO.popen(command, 'w', out: output) do |io|
17
21
  io.write(code)
18
22
  end
19
- @exit_status = $?.exitstatus
20
- end
21
23
 
22
- def command
23
- script_path = File.expand_path('../phantom.js', __FILE__)
24
- "phantomjs #{script_path.shellescape}"
24
+ @exit_status = $?.exitstatus
25
25
  end
26
26
  end
27
27
  end
@@ -3,9 +3,9 @@ require 'opal/cli_runners'
3
3
  module Opal
4
4
  module CliRunners
5
5
  class Server
6
- def initialize(output, port)
7
- @output ||= output || $stdout
8
- @port = port
6
+ def initialize(options)
7
+ @output = options.fetch(:output, $stdout)
8
+ @port = options.fetch(:port, 3000).to_int
9
9
  end
10
10
  attr_reader :output, :port, :server
11
11
 
data/lib/opal/compiler.rb CHANGED
@@ -84,6 +84,7 @@ module Opal
84
84
  # @return [Boolean]
85
85
  compiler_option :arity_check, false, :as => :arity_check?
86
86
 
87
+ # @deprecated
87
88
  # @!method freezing?
88
89
  #
89
90
  # stubs out #freeze and #frozen?
@@ -91,6 +92,7 @@ module Opal
91
92
  # @return [Boolean]
92
93
  compiler_option :freezing, true, :as => :freezing?
93
94
 
95
+ # @deprecated
94
96
  # @!method tainting?
95
97
  #
96
98
  # stubs out #taint, #untaint and #tainted?
@@ -264,6 +266,43 @@ module Opal
264
266
  result
265
267
  end
266
268
 
269
+ def in_ensure
270
+ return unless block_given?
271
+ @in_ensure = true
272
+ result = yield
273
+ @in_ensure = false
274
+
275
+ result
276
+ end
277
+
278
+ def in_ensure?
279
+ @in_ensure
280
+ end
281
+
282
+ # With a block will detect a break in the sexp processed from within
283
+ # the block (see BreakNode).
284
+ #
285
+ # Without a block (but inside a `#has_break?(&block)` call) returns the
286
+ # current result.
287
+ #
288
+ # Works in conjunction with #has_break!
289
+ #
290
+ # @return [Boolean] whether a block has been detected
291
+ def has_break?
292
+ return @break_detected unless block_given?
293
+ @break_detected = false
294
+ result = yield
295
+ detected = @break_detected
296
+ @break_detected = nil
297
+ detected
298
+ end
299
+
300
+ # Marks the current block has having detected a break, but only from inside
301
+ # a `#has_break?(&block)` block.
302
+ def has_break!
303
+ @break_detected = true if @break_detected == false
304
+ end
305
+
267
306
  def in_case
268
307
  return unless block_given?
269
308
  old = @case_stmt
@@ -321,7 +360,7 @@ module Opal
321
360
 
322
361
  case sexp.type
323
362
  # Undefs go from 1 ruby undef a,b,c to multiple JS Opal.udef() calls, so need to treat them as individual statements
324
- # and put the return on the last one
363
+ # and put the return on the last one
325
364
  when :undef
326
365
  last = sexp.pop
327
366
  sexp << returns(last)
@@ -380,9 +419,9 @@ module Opal
380
419
  sexp[3] = returns(sexp[3] || s(:nil))
381
420
  sexp
382
421
  else
383
- s(:js_return, sexp).tap { |s|
384
- s.source = sexp.source
385
- }
422
+ return_sexp = s(:js_return, sexp)
423
+ return_sexp.source = sexp.source
424
+ return_sexp
386
425
  end
387
426
  end
388
427
 
data/lib/opal/config.rb CHANGED
@@ -9,10 +9,11 @@ module Opal
9
9
  freezing_stubs_enabled: true,
10
10
  tainting_stubs_enabled: true,
11
11
  const_missing_enabled: true,
12
- dynamic_require_severity: :error, # :error, :warning or :ignore
12
+ dynamic_require_severity: :warning, # :error, :warning or :ignore
13
13
  irb_enabled: false,
14
14
  inline_operators_enabled: true,
15
15
  source_map_enabled: true,
16
+ stubbed_files: Set.new,
16
17
  }
17
18
  end
18
19
 
@@ -25,6 +26,7 @@ module Opal
25
26
  end
26
27
 
27
28
  COMPILER_KEYS = {
29
+ # Compiler option name: # Config option name
28
30
  method_missing: :method_missing_enabled,
29
31
  arity_check: :arity_check_enabled,
30
32
  freezing: :freezing_stubs_enabled,