opal 0.6.3 → 0.7.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.spectator +2 -0
- data/.spectator-mspec +3 -0
- data/.travis.yml +8 -11
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +8 -43
- data/Gemfile +15 -4
- data/Guardfile +77 -0
- data/README.md +15 -9
- data/Rakefile +36 -12
- data/benchmarks/operators.rb +11 -0
- data/bin/opal +10 -13
- data/bin/opal-build +4 -4
- data/bin/opal-mspec +10 -0
- data/bin/opal-repl +4 -3
- data/examples/sinatra/Gemfile +1 -1
- data/examples/sinatra/config.ru +3 -3
- data/lib/mspec/opal/main.rb.erb +2 -2
- data/lib/mspec/opal/rake_task.rb +31 -24
- data/lib/mspec/opal/runner.rb +18 -1
- data/lib/mspec/opal/sprockets.js +17 -0
- data/lib/opal.rb +1 -34
- data/lib/opal/builder.rb +92 -58
- data/lib/opal/builder_processors.rb +165 -0
- data/lib/opal/cli.rb +85 -144
- data/lib/opal/cli_options.rb +136 -90
- data/lib/opal/cli_runners.rb +10 -0
- data/lib/opal/cli_runners/nodejs.rb +56 -0
- data/lib/opal/cli_runners/phantom.js +35 -0
- data/lib/opal/cli_runners/phantomjs.rb +28 -0
- data/lib/opal/cli_runners/server.rb +54 -0
- data/lib/opal/compiler.rb +35 -16
- data/lib/opal/erb.rb +29 -15
- data/lib/opal/hike_path_finder.rb +18 -0
- data/lib/opal/nodes.rb +1 -0
- data/lib/opal/nodes/call.rb +107 -26
- data/lib/opal/nodes/call_special.rb +31 -6
- data/lib/opal/nodes/class.rb +2 -2
- data/lib/opal/nodes/constants.rb +5 -20
- data/lib/opal/nodes/def.rb +4 -4
- data/lib/opal/nodes/defined.rb +3 -3
- data/lib/opal/nodes/definitions.rb +1 -1
- data/lib/opal/nodes/for.rb +35 -0
- data/lib/opal/nodes/helpers.rb +2 -2
- data/lib/opal/nodes/iter.rb +3 -3
- data/lib/opal/nodes/literal.rb +10 -2
- data/lib/opal/nodes/masgn.rb +2 -2
- data/lib/opal/nodes/module.rb +2 -2
- data/lib/opal/nodes/scope.rb +1 -0
- data/lib/opal/nodes/singleton_class.rb +2 -2
- data/lib/opal/nodes/super.rb +2 -2
- data/lib/opal/nodes/top.rb +30 -3
- data/lib/opal/parser.rb +15 -1
- data/lib/opal/parser/grammar.rb +2571 -2452
- data/lib/opal/parser/grammar.y +37 -5
- data/lib/opal/parser/keywords.rb +2 -0
- data/lib/opal/parser/lexer.rb +21 -11
- data/lib/opal/path_reader.rb +28 -0
- data/lib/opal/paths.rb +38 -0
- data/lib/opal/source_map.rb +32 -15
- data/lib/opal/sprockets/environment.rb +9 -2
- data/lib/opal/sprockets/erb.rb +1 -2
- data/lib/opal/sprockets/path_reader.rb +34 -0
- data/lib/opal/sprockets/processor.rb +40 -39
- data/lib/opal/sprockets/server.rb +47 -33
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +10 -5
- data/opal/README.md +6 -0
- data/opal/corelib/array.rb +36 -4
- data/opal/corelib/array/inheritance.rb +6 -6
- data/opal/corelib/basic_object.rb +9 -9
- data/opal/corelib/boolean.rb +1 -1
- data/opal/corelib/class.rb +12 -12
- data/opal/corelib/dir.rb +20 -0
- data/opal/corelib/enumerable.rb +42 -42
- data/opal/corelib/enumerator.rb +1 -1
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +56 -0
- data/opal/corelib/hash.rb +5 -5
- data/opal/corelib/helpers.rb +3 -3
- data/opal/corelib/io.rb +13 -10
- data/opal/corelib/kernel.rb +44 -68
- data/opal/corelib/method.rb +1 -1
- data/opal/corelib/module.rb +89 -114
- data/opal/corelib/nil_class.rb +1 -1
- data/opal/corelib/numeric.rb +27 -23
- data/opal/corelib/proc.rb +5 -5
- data/opal/corelib/range.rb +8 -4
- data/opal/corelib/regexp.rb +5 -5
- data/opal/corelib/runtime.js +589 -272
- data/opal/corelib/string.rb +52 -37
- data/opal/corelib/string/inheritance.rb +5 -5
- data/opal/corelib/time.rb +102 -52
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal.rb +2 -0
- data/package.json +9 -0
- data/spec/filters/bugs/array.rb +0 -6
- data/spec/filters/bugs/language.rb +4 -0
- data/spec/filters/bugs/numeric.rb +7 -6
- data/spec/filters/bugs/opal.rb +2 -0
- data/spec/filters/bugs/regexp.rb +4 -0
- data/spec/filters/bugs/string.rb +0 -7
- data/spec/filters/bugs/stringscanner.rb +4 -1
- data/spec/filters/unsupported/private_methods.rb +2 -0
- data/spec/lib/builder_processors_spec.rb +27 -0
- data/spec/lib/builder_spec.rb +66 -0
- data/spec/{cli → lib}/cli_spec.rb +60 -5
- data/spec/{cli → lib}/compiler_spec.rb +66 -5
- data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
- data/spec/lib/fixtures/no_requires.rb +1 -0
- data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
- data/spec/lib/fixtures/require_tree_test.rb +3 -0
- data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
- data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
- data/spec/lib/fixtures/requires.rb +7 -0
- data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
- data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
- data/spec/lib/hike_path_finder_spec.rb +23 -0
- data/spec/{cli → lib}/lexer_spec.rb +1 -1
- data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
- data/spec/{cli → lib}/parser/and_spec.rb +1 -1
- data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
- data/spec/{cli → lib}/parser/block_spec.rb +1 -1
- data/spec/{cli → lib}/parser/break_spec.rb +1 -1
- data/spec/{cli → lib}/parser/call_spec.rb +1 -1
- data/spec/{cli → lib}/parser/class_spec.rb +1 -1
- data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
- data/spec/{cli → lib}/parser/def_spec.rb +1 -1
- data/spec/{cli → lib}/parser/if_spec.rb +1 -1
- data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
- data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
- data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
- data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/module_spec.rb +1 -1
- data/spec/{cli → lib}/parser/not_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
- data/spec/{cli → lib}/parser/or_spec.rb +1 -1
- data/spec/{cli → lib}/parser/return_spec.rb +1 -1
- data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
- data/spec/{cli → lib}/parser/string_spec.rb +8 -1
- data/spec/{cli → lib}/parser/super_spec.rb +1 -1
- data/spec/lib/parser/unary_spec.rb +48 -0
- data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
- data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
- data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
- data/spec/{cli → lib}/parser/while_spec.rb +1 -1
- data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
- data/spec/lib/path_reader_spec.rb +24 -0
- data/spec/lib/shared/path_finder_shared.rb +19 -0
- data/spec/lib/shared/path_reader_shared.rb +31 -0
- data/spec/lib/spec_helper.rb +9 -0
- data/spec/lib/sprockets/environment_spec.rb +30 -0
- data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
- data/spec/lib/sprockets/path_reader_spec.rb +25 -0
- data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
- data/spec/lib/sprockets/server_spec.rb +20 -0
- data/spec/opal/compiler/irb_spec.rb +11 -11
- data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
- data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
- data/spec/opal/core/source_map_spec.rb +2 -2
- data/spec/opal/core/string_spec.rb +11 -0
- data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
- data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
- data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
- data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
- data/spec/rubyspecs +54 -11
- data/spec/spec_helper.rb +18 -3
- data/spec/support/mspec_rspec_adapter.rb +33 -0
- data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
- data/stdlib/README.md +3 -0
- data/stdlib/benchmark.rb +10 -0
- data/stdlib/date.rb +2 -2
- data/stdlib/dir.rb +1 -5
- data/stdlib/file.rb +1 -7
- data/stdlib/json.rb +10 -1
- data/stdlib/native.rb +5 -5
- data/stdlib/nodejs.rb +5 -0
- data/stdlib/nodejs/dir.rb +13 -0
- data/stdlib/nodejs/file.rb +98 -0
- data/stdlib/nodejs/fileutils.rb +26 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/irb.rb +45 -0
- data/stdlib/nodejs/process.rb +16 -0
- data/stdlib/nodejs/require.rb +32 -0
- data/stdlib/nodejs/rubygems.rb +68 -0
- data/stdlib/nodejs/runtime.rb +25 -0
- data/stdlib/nodejs/yaml.rb +11 -0
- data/stdlib/opal-parser.rb +1 -2
- data/stdlib/opal-source-maps.rb +2 -0
- data/stdlib/phantomjs.rb +8 -0
- data/stdlib/process.rb +10 -0
- data/stdlib/promise.rb +12 -4
- data/stdlib/set.rb +27 -0
- data/stdlib/source_map.rb +5 -63
- data/stdlib/source_map/map.rb +220 -0
- data/stdlib/source_map/mapping.rb +26 -0
- data/stdlib/source_map/offset.rb +88 -0
- data/stdlib/source_map/version.rb +3 -0
- data/stdlib/source_map/vlq.rb +77 -101
- data/stdlib/sourcemap.rb +1 -0
- data/stdlib/strscan.rb +7 -1
- data/stdlib/template.rb +1 -1
- data/stdlib/thread.rb +147 -7
- metadata +238 -104
- data/lib/mspec/opal/mspec_fixes.rb +0 -87
- data/spec/cli/sprockets/environment_spec.rb +0 -14
- data/spec/filters/bugs/symbol.rb +0 -5
- data/spec/opal/core/kernel/warn_spec.rb +0 -83
- data/spec/opal/core/language/numbers_spec.rb +0 -60
- data/stdlib/opal-source-maps.js.erb +0 -2
- data/stdlib/source_map/generator.rb +0 -251
- data/stdlib/source_map/parser.rb +0 -102
data/lib/opal/cli_options.rb
CHANGED
|
@@ -3,101 +3,147 @@ require 'optparse'
|
|
|
3
3
|
module Opal
|
|
4
4
|
class CLIOptions < OptionParser
|
|
5
5
|
def initialize
|
|
6
|
+
super
|
|
6
7
|
@options = {}
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
dynamic_require_levels = %w[error warning ignore]
|
|
82
|
-
opts.on('-D', '--dynamic-require LEVEL', dynamic_require_levels,
|
|
83
|
-
'Set levelDynamic require severity') do |level|
|
|
84
|
-
options[:dynamic_require_severity] = level.to_sym
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
opts.on('-P', '--no-source-map', 'Disable source map') do |value|
|
|
88
|
-
options[:source_map_enabled] = false
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
opts.on('-F', '--file FILE', 'Set filename for compiled code') do |file|
|
|
92
|
-
options[:file] = file
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
opts.on("--[no-]irb", "IRB var mode") do |flag|
|
|
96
|
-
options[:irb] = flag
|
|
97
|
-
end
|
|
9
|
+
self.banner = 'Usage: opal [options] -- [programfile]'
|
|
10
|
+
|
|
11
|
+
separator ''
|
|
12
|
+
|
|
13
|
+
on('-v', '--verbose', 'print version number, then turn on verbose mode') do
|
|
14
|
+
print_version
|
|
15
|
+
options[:verbose] = true # TODO: print some warnings when verbose = true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
on('--verbose', 'turn on verbose mode') do
|
|
19
|
+
options[:verbose] = true # TODO: print some warnings when verbose = true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
on('--version', 'Print the version') do
|
|
23
|
+
print_version
|
|
24
|
+
exit
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
on("-h", "--help", "Show this message") do
|
|
28
|
+
puts self
|
|
29
|
+
exit
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
section 'Basic Options:'
|
|
34
|
+
|
|
35
|
+
on('-I', '--include DIR',
|
|
36
|
+
'Append a load path (may be used more than once)') do |i|
|
|
37
|
+
options[:load_paths] ||= []
|
|
38
|
+
options[:load_paths] << i
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
on('-e', '--eval SOURCE', String,
|
|
42
|
+
'One line of script. Several -e\'s allowed. Omit [programfile]') do |source|
|
|
43
|
+
options[:evals] ||= []
|
|
44
|
+
options[:evals] << source
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
on('-r', '--require LIBRARY', String,
|
|
48
|
+
'Require the library before executing your script') do |library|
|
|
49
|
+
options[:requires] ||= []
|
|
50
|
+
options[:requires] << library
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
on('-s', '--stub FILE', String, 'Stubbed files will be compiled as empty files') do |stub|
|
|
54
|
+
options[:stubs] ||= []
|
|
55
|
+
options[:stubs] << stub
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
on('-p', '--preload FILE', String, 'Preloaded files will be prepared for dynamic requires') do |stub|
|
|
59
|
+
options[:preload] ||= []
|
|
60
|
+
options[:preload] << stub
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
on('-g', '--gem GEM_NAME', String, 'Adds the specified GEM_NAME to Opal\'s load path.') do |g|
|
|
64
|
+
options[:gems] ||= []
|
|
65
|
+
options[:gems] << g
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
section 'Running Options:'
|
|
69
|
+
|
|
70
|
+
on('--sexp', 'Show Sexps') do
|
|
71
|
+
options[:sexp] = true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
on('-m', '--map', 'Show sourcemap') do
|
|
75
|
+
options[:map] = true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
on('-c', '--compile', 'Compile to JavaScript') do
|
|
79
|
+
options[:compile] = true
|
|
98
80
|
end
|
|
81
|
+
|
|
82
|
+
on('--runner RUNNER', %w[nodejs server phantomjs], 'Choose the runner: nodejs (default), server') do |runner|
|
|
83
|
+
options[:runner] = runner.to_sym
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
on('--server-port PORT', 'Set the port for the server runner (default port: 3000)') do |port|
|
|
87
|
+
options[:runner] = :server
|
|
88
|
+
options[:port] = port.to_i
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
section 'Compilation Options:'
|
|
93
|
+
|
|
94
|
+
on('-M', '--no-method-missing', 'Enable/Disable method missing') do
|
|
95
|
+
options[:method_missing] = false
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
on('-O', '--no-opal', 'Enable/Disable implicit `require "opal"`') do
|
|
99
|
+
options[:skip_opal_require] = true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
on('-A', '--arity-check', 'Enable arity check') do
|
|
103
|
+
options[:arity_check] = true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
on('-V', 'Enable inline Operators') do
|
|
107
|
+
options[:inline_operators] = true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
dynamic_require_levels = %w[error warning ignore]
|
|
111
|
+
on('-D', '--dynamic-require LEVEL', dynamic_require_levels,
|
|
112
|
+
'Set level of dynamic require severity.',
|
|
113
|
+
"(deafult: error, values: #{dynamic_require_levels.join(', ')})") do |level|
|
|
114
|
+
options[:dynamic_require_severity] = level.to_sym
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
on('-P', '--source-map [FILE]', 'Enable/Disable source map') do |file|
|
|
118
|
+
options[:source_map_enabled] = true
|
|
119
|
+
options[:source_map_file] = file if file
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
on('-F', '--file FILE', 'Set filename for compiled code') do |file|
|
|
123
|
+
options[:file] = file
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
on("--irb", "Enable IRB var mode") do
|
|
127
|
+
options[:irb] = true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
separator ''
|
|
99
131
|
end
|
|
100
132
|
|
|
101
133
|
attr_reader :options
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def print_version
|
|
139
|
+
require 'opal/version'
|
|
140
|
+
puts "Opal v#{Opal::VERSION}"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def section title
|
|
144
|
+
separator ''
|
|
145
|
+
separator title
|
|
146
|
+
separator ''
|
|
147
|
+
end
|
|
102
148
|
end
|
|
103
149
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'opal/cli_runners'
|
|
2
|
+
|
|
3
|
+
module Opal
|
|
4
|
+
module CliRunners
|
|
5
|
+
class Nodejs
|
|
6
|
+
def initialize(output)
|
|
7
|
+
@output ||= output
|
|
8
|
+
end
|
|
9
|
+
attr_reader :output
|
|
10
|
+
|
|
11
|
+
def puts(*args)
|
|
12
|
+
output.puts(*args)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def node_modules
|
|
16
|
+
File.expand_path("../../../../node_modules", __FILE__)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run(code, argv)
|
|
20
|
+
require 'tempfile'
|
|
21
|
+
tempfile = Tempfile.new('opal-nodejs-runner-')
|
|
22
|
+
# tempfile = File.new('opal-nodejs-runner.js', 'w') # for debugging
|
|
23
|
+
tempfile.write code
|
|
24
|
+
tempfile.close
|
|
25
|
+
system_with_output({'NODE_PATH' => node_modules}, 'node', tempfile.path , *argv)
|
|
26
|
+
rescue Errno::ENOENT
|
|
27
|
+
raise MissingNodeJS, 'Please install Node.js to be able to run Opal scripts.'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Let's support fake IO objects like StringIO
|
|
31
|
+
def system_with_output(env, *cmd)
|
|
32
|
+
io_output = IO.try_convert(output)
|
|
33
|
+
return system(env,*cmd) if io_output
|
|
34
|
+
|
|
35
|
+
if RUBY_PLATFORM == 'java'
|
|
36
|
+
# JRuby has issues in dealing with subprocesses (at least up to 1.7.15)
|
|
37
|
+
# @headius told me it's mostly fixed on master, but while we wait for it
|
|
38
|
+
# to ship here's a tempfile workaround.
|
|
39
|
+
require 'tempfile'
|
|
40
|
+
require 'shellwords'
|
|
41
|
+
tempfile = Tempfile.new('opal-node-output')
|
|
42
|
+
system(env,cmd.shelljoin+" > #{tempfile.path}")
|
|
43
|
+
captured_output = File.read tempfile.path
|
|
44
|
+
tempfile.close
|
|
45
|
+
else
|
|
46
|
+
require 'open3'
|
|
47
|
+
captured_output, status = Open3.capture2(env,*cmd)
|
|
48
|
+
end
|
|
49
|
+
output.write captured_output
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class MissingNodeJS < RunnerError
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var page = require('webpage').create();
|
|
2
|
+
var fs = require('fs');
|
|
3
|
+
var system = require('system');
|
|
4
|
+
|
|
5
|
+
page.onConsoleMessage = function(msg) {
|
|
6
|
+
system.stdout.write(msg);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
var opal_code = fs.read('/dev/stdin');
|
|
10
|
+
|
|
11
|
+
page.onCallback = function(data) {
|
|
12
|
+
switch (data[0]) {
|
|
13
|
+
case 'exit':
|
|
14
|
+
var status = data[1] || 0;
|
|
15
|
+
phantom.exit(status);
|
|
16
|
+
case 'stdout':
|
|
17
|
+
system.stdout.write(data[1] || '');
|
|
18
|
+
break;
|
|
19
|
+
case 'stderr':
|
|
20
|
+
system.stderr.write(data[1] || '');
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
console.error('Unknown callback data: ', data);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
page.content = '<!doctype html>'+
|
|
28
|
+
'<html>'+
|
|
29
|
+
' <head><meta charset="utf-8"/></head>'+
|
|
30
|
+
" <body><script>//<![CDATA[\n"+
|
|
31
|
+
opal_code+
|
|
32
|
+
" //]]></script>"+
|
|
33
|
+
' <script>callPhantom(["exit", 0]);</script></body>\n'+
|
|
34
|
+
' </body>'+
|
|
35
|
+
'</html>';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
module Opal
|
|
4
|
+
module CliRunners
|
|
5
|
+
class Phantomjs
|
|
6
|
+
def initialize(output = $stdout)
|
|
7
|
+
@output = output
|
|
8
|
+
end
|
|
9
|
+
attr_reader :output
|
|
10
|
+
|
|
11
|
+
def run(code, argv)
|
|
12
|
+
unless argv.empty?
|
|
13
|
+
raise ArgumentError, 'Program arguments are not supported on the PhantomJS runner'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
phantomjs = IO.popen(command, 'w', out: output) do |io|
|
|
17
|
+
io.write(code)
|
|
18
|
+
end
|
|
19
|
+
exit $?.exitstatus
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def command
|
|
23
|
+
script_path = File.expand_path('../phantom.js', __FILE__)
|
|
24
|
+
"phantomjs #{script_path.shellescape}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'opal/cli_runners'
|
|
2
|
+
|
|
3
|
+
module Opal
|
|
4
|
+
module CliRunners
|
|
5
|
+
class Server
|
|
6
|
+
def initialize(output, port)
|
|
7
|
+
@output ||= output || $stdout
|
|
8
|
+
@port = port
|
|
9
|
+
end
|
|
10
|
+
attr_reader :output, :port, :server
|
|
11
|
+
|
|
12
|
+
def run(source, argv)
|
|
13
|
+
unless argv.empty?
|
|
14
|
+
raise ArgumentError, 'Program arguments are not supported on the PhantomJS runner'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
require 'rack'
|
|
18
|
+
require 'webrick'
|
|
19
|
+
require 'logger'
|
|
20
|
+
|
|
21
|
+
@server = Rack::Server.start(
|
|
22
|
+
:app => app(source),
|
|
23
|
+
:Port => port,
|
|
24
|
+
:AccessLog => [],
|
|
25
|
+
:Logger => Logger.new(output)
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def app(source)
|
|
30
|
+
lambda do |env|
|
|
31
|
+
case env['PATH_INFO']
|
|
32
|
+
when '/'
|
|
33
|
+
body = <<-HTML
|
|
34
|
+
<!doctype html>
|
|
35
|
+
<html>
|
|
36
|
+
<head>
|
|
37
|
+
<meta charset="utf-8"/>
|
|
38
|
+
<script>
|
|
39
|
+
//<![CDATA[
|
|
40
|
+
#{source}
|
|
41
|
+
//]]>
|
|
42
|
+
</script>
|
|
43
|
+
</head>
|
|
44
|
+
</html>
|
|
45
|
+
HTML
|
|
46
|
+
[200, {}, [body]]
|
|
47
|
+
else
|
|
48
|
+
[404, {}, [body]]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/opal/compiler.rb
CHANGED
|
@@ -5,7 +5,7 @@ require 'opal/nodes'
|
|
|
5
5
|
|
|
6
6
|
module Opal
|
|
7
7
|
def self.compile(source, options = {})
|
|
8
|
-
Compiler.new
|
|
8
|
+
Compiler.new(source, options).compile
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
class Compiler
|
|
@@ -17,9 +17,13 @@ module Opal
|
|
|
17
17
|
COMPARE = %w[< > <= >=]
|
|
18
18
|
|
|
19
19
|
# defines a compiler option, also creating method of form 'name?'
|
|
20
|
-
def self.compiler_option(name, default_value,
|
|
20
|
+
def self.compiler_option(name, default_value, options = {})
|
|
21
|
+
mid = options[:as]
|
|
22
|
+
valid_values = options[:valid_values]
|
|
21
23
|
define_method(mid || name) do
|
|
22
|
-
@options.fetch(name) { default_value }
|
|
24
|
+
value = @options.fetch(name) { default_value }
|
|
25
|
+
raise ArgumentError if valid_values and not(valid_values.include?(value))
|
|
26
|
+
value
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
|
|
@@ -27,19 +31,22 @@ module Opal
|
|
|
27
31
|
compiler_option :file, '(file)'
|
|
28
32
|
|
|
29
33
|
# adds method stubs for all used methods in file
|
|
30
|
-
compiler_option :method_missing, true, :method_missing?
|
|
34
|
+
compiler_option :method_missing, true, :as => :method_missing?
|
|
31
35
|
|
|
32
36
|
# adds an arity check to every method definition
|
|
33
|
-
compiler_option :arity_check, false, :arity_check?
|
|
34
|
-
|
|
35
|
-
# checks every constant access, delagating to const_missing if needed
|
|
36
|
-
compiler_option :const_missing, false, :const_missing?
|
|
37
|
+
compiler_option :arity_check, false, :as => :arity_check?
|
|
37
38
|
|
|
38
39
|
# compile top level local vars with support for irb style vars
|
|
39
|
-
compiler_option :irb, false, :irb?
|
|
40
|
+
compiler_option :irb, false, :as => :irb?
|
|
40
41
|
|
|
41
42
|
# how to handle dynamic requires (:error, :warning, :ignore)
|
|
42
|
-
compiler_option :dynamic_require_severity, :error
|
|
43
|
+
compiler_option :dynamic_require_severity, :error, :valid_values => [:error, :warning, :ignore]
|
|
44
|
+
|
|
45
|
+
# Prepare the code for future requires
|
|
46
|
+
compiler_option :requirable, false, :as => :requirable?
|
|
47
|
+
|
|
48
|
+
# are operators compiled inline
|
|
49
|
+
compiler_option :inline_operators, false, :as => :inline_operators?
|
|
43
50
|
|
|
44
51
|
attr_reader :result, :fragments
|
|
45
52
|
|
|
@@ -52,16 +59,15 @@ module Opal
|
|
|
52
59
|
# Any content in __END__ special construct
|
|
53
60
|
attr_reader :eof_content
|
|
54
61
|
|
|
55
|
-
def initialize
|
|
62
|
+
def initialize(source, options = {})
|
|
63
|
+
@source = source
|
|
56
64
|
@indent = ''
|
|
57
65
|
@unique = 0
|
|
58
|
-
@options =
|
|
66
|
+
@options = options
|
|
59
67
|
end
|
|
60
68
|
|
|
61
69
|
# Compile some ruby code to a string.
|
|
62
|
-
def compile
|
|
63
|
-
@source = source
|
|
64
|
-
@options.update options
|
|
70
|
+
def compile
|
|
65
71
|
@parser = Parser.new
|
|
66
72
|
|
|
67
73
|
@sexp = s(:top, @parser.parse(@source, self.file) || s(:nil))
|
|
@@ -81,6 +87,11 @@ module Opal
|
|
|
81
87
|
@helpers ||= Set.new([:breaker, :slice])
|
|
82
88
|
end
|
|
83
89
|
|
|
90
|
+
# Operator helpers
|
|
91
|
+
def operator_helpers
|
|
92
|
+
@operator_helpers ||= Set.new
|
|
93
|
+
end
|
|
94
|
+
|
|
84
95
|
# Method calls made in this file
|
|
85
96
|
def method_calls
|
|
86
97
|
@method_calls ||= Set.new
|
|
@@ -97,7 +108,7 @@ module Opal
|
|
|
97
108
|
# method simply appends the filename and curent line number onto
|
|
98
109
|
# the message and issues a warning.
|
|
99
110
|
def warning(msg, line = nil)
|
|
100
|
-
warn "#{msg} :#{file}:#{line}"
|
|
111
|
+
warn "WARNING: #{msg} :#{file}:#{line}"
|
|
101
112
|
end
|
|
102
113
|
|
|
103
114
|
# Instances of `Scope` can use this to determine the current
|
|
@@ -182,6 +193,8 @@ module Opal
|
|
|
182
193
|
# Process the given sexp by creating a node instance, based on its type,
|
|
183
194
|
# and compiling it to fragments.
|
|
184
195
|
def process(sexp, level = :expr)
|
|
196
|
+
return fragment('') if sexp == nil
|
|
197
|
+
|
|
185
198
|
if handler = handlers[sexp.type]
|
|
186
199
|
return handler.new(sexp, level, self).compile_to_fragments
|
|
187
200
|
else
|
|
@@ -198,6 +211,12 @@ module Opal
|
|
|
198
211
|
@requires ||= []
|
|
199
212
|
end
|
|
200
213
|
|
|
214
|
+
# An array of trees required in this file
|
|
215
|
+
# (typically by calling #require_tree)
|
|
216
|
+
def required_trees
|
|
217
|
+
@required_trees ||= []
|
|
218
|
+
end
|
|
219
|
+
|
|
201
220
|
# The last sexps in method bodies, for example, need to be returned
|
|
202
221
|
# in the compiled javascript. Due to syntax differences between
|
|
203
222
|
# javascript any ruby, some sexps need to be handled specially. For
|