opal 0.3.11 → 0.3.15
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/Gemfile +10 -0
- data/LICENSE +20 -0
- data/README.md +11 -116
- data/Rakefile +126 -0
- data/bin/opal +1 -2
- data/docs/spec_runner.html +16 -0
- data/index.html +434 -0
- data/lib/opal.rb +14 -15
- data/lib/opal/builder.rb +46 -148
- data/lib/opal/command.rb +45 -115
- data/lib/opal/context.rb +139 -78
- data/lib/opal/dependency_builder.rb +34 -0
- data/lib/opal/environment.rb +92 -0
- data/lib/opal/parser/grammar.rb +4915 -0
- data/lib/opal/{parser.y → parser/grammar.y} +430 -284
- data/lib/opal/parser/lexer.rb +1329 -0
- data/lib/opal/parser/parser.rb +1460 -0
- data/lib/opal/parser/scope.rb +140 -0
- data/lib/opal/parser/sexp.rb +17 -0
- data/lib/opal/version.rb +2 -1
- data/opal.gemspec +23 -0
- data/opal.js +3149 -4162
- data/runtime/README.md +25 -0
- data/runtime/corelib/alpha.rb +10 -0
- data/runtime/corelib/array.rb +962 -0
- data/runtime/corelib/basic_object.rb +66 -0
- data/runtime/corelib/boolean.rb +44 -0
- data/runtime/corelib/class.rb +43 -0
- data/runtime/corelib/comparable.rb +25 -0
- data/runtime/corelib/complex.rb +2 -0
- data/runtime/corelib/dir.rb +29 -0
- data/runtime/corelib/enumerable.rb +316 -0
- data/runtime/corelib/enumerator.rb +80 -0
- data/runtime/corelib/error.rb +25 -0
- data/runtime/corelib/file.rb +80 -0
- data/runtime/corelib/hash.rb +503 -0
- data/runtime/corelib/io.rb +44 -0
- data/runtime/corelib/kernel.rb +237 -0
- data/runtime/corelib/load_order +29 -0
- data/runtime/corelib/match_data.rb +37 -0
- data/runtime/corelib/module.rb +171 -0
- data/runtime/corelib/native.rb +50 -0
- data/runtime/corelib/nil_class.rb +47 -0
- data/runtime/corelib/numeric.rb +219 -0
- data/runtime/corelib/object.rb +21 -0
- data/runtime/corelib/proc.rb +42 -0
- data/runtime/corelib/range.rb +38 -0
- data/runtime/corelib/rational.rb +16 -0
- data/runtime/corelib/regexp.rb +63 -0
- data/runtime/corelib/string.rb +185 -0
- data/runtime/corelib/struct.rb +97 -0
- data/runtime/corelib/time.rb +196 -0
- data/runtime/corelib/top_self.rb +7 -0
- data/runtime/gemlib/alpha.rb +5 -0
- data/runtime/gemlib/kernel.rb +17 -0
- data/runtime/gemlib/load_order +2 -0
- data/runtime/kernel/class.js +256 -0
- data/runtime/kernel/debug.js +42 -0
- data/runtime/kernel/init.js +114 -0
- data/runtime/kernel/load_order +5 -0
- data/runtime/kernel/loader.js +151 -0
- data/runtime/kernel/runtime.js +414 -0
- data/runtime/spec/README.md +34 -0
- data/runtime/spec/core/array/allocate_spec.rb +15 -0
- data/runtime/spec/core/array/append_spec.rb +31 -0
- data/runtime/spec/core/array/assoc_spec.rb +29 -0
- data/runtime/spec/core/array/at_spec.rb +38 -0
- data/runtime/spec/core/array/clear_spec.rb +22 -0
- data/runtime/spec/core/array/collect_spec.rb +3 -0
- data/runtime/spec/core/array/compact_spec.rb +42 -0
- data/runtime/spec/core/array/concat_spec.rb +21 -0
- data/runtime/spec/core/array/constructor_spec.rb +24 -0
- data/runtime/spec/core/array/count_spec.rb +11 -0
- data/runtime/spec/core/array/delete_at_spec.rb +31 -0
- data/runtime/spec/core/array/delete_if_spec.rb +24 -0
- data/runtime/spec/core/array/delete_spec.rb +26 -0
- data/runtime/spec/core/array/each_index_spec.rb +33 -0
- data/runtime/spec/core/array/each_spec.rb +11 -0
- data/runtime/spec/core/array/element_reference_spec.rb +136 -0
- data/runtime/spec/core/array/element_set_spec.rb +7 -0
- data/runtime/spec/core/array/empty_spec.rb +10 -0
- data/runtime/spec/core/array/eql_spec.rb +3 -0
- data/runtime/spec/core/array/equal_value_spec.rb +3 -0
- data/runtime/spec/core/array/fetch_spec.rb +26 -0
- data/runtime/spec/core/array/first_spec.rb +54 -0
- data/runtime/spec/core/array/fixtures/classes.rb +8 -0
- data/runtime/spec/core/array/flatten_spec.rb +41 -0
- data/runtime/spec/core/array/include_spec.rb +20 -0
- data/runtime/spec/core/array/insert_spec.rb +59 -0
- data/runtime/spec/core/array/last_spec.rb +57 -0
- data/runtime/spec/core/array/length_spec.rb +3 -0
- data/runtime/spec/core/array/map_spec.rb +3 -0
- data/runtime/spec/core/array/plus_spec.rb +16 -0
- data/runtime/spec/core/array/pop_spec.rb +79 -0
- data/runtime/spec/core/array/push_spec.rb +19 -0
- data/runtime/spec/core/array/rassoc_spec.rb +12 -0
- data/runtime/spec/core/array/reject_spec.rb +54 -0
- data/runtime/spec/core/array/replace_spec.rb +3 -0
- data/runtime/spec/core/array/reverse_each_spec.rb +18 -0
- data/runtime/spec/core/array/reverse_spec.rb +9 -0
- data/runtime/spec/core/array/shared/collect.rb +53 -0
- data/runtime/spec/core/array/shared/eql.rb +19 -0
- data/runtime/spec/core/array/shared/length.rb +6 -0
- data/runtime/spec/core/array/shared/replace.rb +31 -0
- data/runtime/spec/core/class/new_spec.rb +19 -0
- data/runtime/spec/core/enumerable/all_spec.rb +102 -0
- data/runtime/spec/core/enumerable/any_spec.rb +115 -0
- data/runtime/spec/core/enumerable/collect_spec.rb +3 -0
- data/runtime/spec/core/enumerable/count_spec.rb +29 -0
- data/runtime/spec/core/enumerable/detect_spec.rb +3 -0
- data/runtime/spec/core/enumerable/find_spec.rb +3 -0
- data/runtime/spec/core/enumerable/fixtures/classes.rb +26 -0
- data/runtime/spec/core/enumerable/shared/collect.rb +12 -0
- data/runtime/spec/core/enumerable/shared/entries.rb +7 -0
- data/runtime/spec/core/enumerable/shared/find.rb +49 -0
- data/runtime/spec/core/enumerable/to_a_spec.rb +7 -0
- data/runtime/spec/core/false/and_spec.rb +11 -0
- data/runtime/spec/core/false/inspect_spec.rb +7 -0
- data/runtime/spec/core/false/or_spec.rb +11 -0
- data/runtime/spec/core/false/to_s_spec.rb +7 -0
- data/runtime/spec/core/false/xor_spec.rb +11 -0
- data/runtime/spec/core/hash/allocate_spec.rb +15 -0
- data/runtime/spec/core/hash/assoc_spec.rb +29 -0
- data/runtime/spec/core/hash/clear_spec.rb +21 -0
- data/runtime/spec/core/hash/clone_spec.rb +12 -0
- data/runtime/spec/core/hash/default_spec.rb +6 -0
- data/runtime/spec/core/hash/delete_if_spec.rb +15 -0
- data/runtime/spec/core/hash/element_reference_spec.rb +16 -0
- data/runtime/spec/core/hash/element_set_spec.rb +8 -0
- data/runtime/spec/core/hash/new_spec.rb +13 -0
- data/runtime/spec/core/matchdata/to_a_spec.rb +7 -0
- data/runtime/spec/core/nil/and_spec.rb +12 -0
- data/runtime/spec/core/nil/inspect_spec.rb +8 -0
- data/runtime/spec/core/nil/nil_spec.rb +8 -0
- data/runtime/spec/core/nil/or_spec.rb +12 -0
- data/runtime/spec/core/nil/to_a_spec.rb +8 -0
- data/runtime/spec/core/nil/to_f_spec.rb +12 -0
- data/runtime/spec/core/nil/to_i_spec.rb +12 -0
- data/runtime/spec/core/nil/to_s_spec.rb +8 -0
- data/runtime/spec/core/nil/xor_spec.rb +12 -0
- data/runtime/spec/core/numeric/equal_value_spec.rb +11 -0
- data/runtime/spec/core/object/is_a_spec.rb +2 -0
- data/runtime/spec/core/object/shared/kind_of.rb +0 -0
- data/runtime/spec/core/regexp/match_spec.rb +23 -0
- data/runtime/spec/core/regexp/shared/match.rb +11 -0
- data/runtime/spec/core/symbol/to_proc_spec.rb +8 -0
- data/runtime/spec/core/true/and_spec.rb +11 -0
- data/runtime/spec/core/true/inspect_spec.rb +7 -0
- data/runtime/spec/core/true/or_spec.rb +11 -0
- data/runtime/spec/core/true/to_s_spec.rb +7 -0
- data/runtime/spec/core/true/xor_spec.rb +11 -0
- data/runtime/spec/language/alias_spec.rb +25 -0
- data/runtime/spec/language/and_spec.rb +62 -0
- data/runtime/spec/language/array_spec.rb +68 -0
- data/runtime/spec/language/block_spec.rb +105 -0
- data/runtime/spec/language/break_spec.rb +49 -0
- data/runtime/spec/language/case_spec.rb +165 -0
- data/runtime/spec/language/defined_spec.rb +80 -0
- data/runtime/spec/language/ensure_spec.rb +82 -0
- data/runtime/spec/language/fixtures/block.rb +19 -0
- data/runtime/spec/language/fixtures/break.rb +39 -0
- data/runtime/spec/language/fixtures/defined.rb +9 -0
- data/runtime/spec/language/fixtures/ensure.rb +37 -0
- data/runtime/spec/language/fixtures/next.rb +46 -0
- data/runtime/spec/language/fixtures/send.rb +36 -0
- data/runtime/spec/language/fixtures/super.rb +43 -0
- data/runtime/spec/language/hash_spec.rb +43 -0
- data/runtime/spec/language/if_spec.rb +278 -0
- data/runtime/spec/language/loop_spec.rb +32 -0
- data/runtime/spec/language/next_spec.rb +128 -0
- data/runtime/spec/language/or_spec.rb +65 -0
- data/runtime/spec/language/predefined_spec.rb +21 -0
- data/runtime/spec/language/regexp/interpolation_spec.rb +9 -0
- data/runtime/spec/language/regexp_spec.rb +7 -0
- data/runtime/spec/language/send_spec.rb +105 -0
- data/runtime/spec/language/string_spec.rb +4 -0
- data/runtime/spec/language/super_spec.rb +18 -0
- data/runtime/spec/language/symbol_spec.rb +41 -0
- data/runtime/spec/language/undef_spec.rb +16 -0
- data/runtime/spec/language/unless_spec.rb +44 -0
- data/runtime/spec/language/until_spec.rb +137 -0
- data/runtime/spec/language/variables_spec.rb +28 -0
- data/runtime/spec/language/versions/hash_1.9.rb +20 -0
- data/runtime/spec/language/while_spec.rb +175 -0
- data/runtime/spec/library/stringscanner/scan_spec.rb +36 -0
- data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +49 -0
- data/runtime/spec/opal/opal/defined_spec.rb +15 -0
- data/runtime/spec/opal/opal/function_spec.rb +11 -0
- data/runtime/spec/opal/opal/native_spec.rb +16 -0
- data/runtime/spec/opal/opal/null_spec.rb +10 -0
- data/runtime/spec/opal/opal/number_spec.rb +11 -0
- data/runtime/spec/opal/opal/object_spec.rb +16 -0
- data/runtime/spec/opal/opal/string_spec.rb +11 -0
- data/runtime/spec/opal/opal/typeof_spec.rb +9 -0
- data/runtime/spec/opal/opal/undefined_spec.rb +10 -0
- data/runtime/spec/opal/true/case_compare_spec.rb +12 -0
- data/runtime/spec/opal/true/class_spec.rb +10 -0
- data/runtime/spec/spec_helper.rb +25 -0
- data/runtime/stdlib/base64.rb +91 -0
- data/runtime/stdlib/date.rb +4 -0
- data/{stdlib → runtime/stdlib}/dev.rb +0 -0
- data/runtime/stdlib/forwardable.rb +33 -0
- data/runtime/stdlib/optparse.rb +0 -0
- data/runtime/stdlib/pp.rb +6 -0
- data/{stdlib → runtime/stdlib}/racc/parser.rb +0 -0
- data/runtime/stdlib/rbconfig.rb +0 -0
- data/runtime/stdlib/si.rb +17 -0
- data/runtime/stdlib/strscan.rb +53 -0
- data/runtime/stdlib/uri.rb +111 -0
- data/runtime/stdlib/uri/common.rb +1014 -0
- data/runtime/stdlib/uri/ftp.rb +261 -0
- data/runtime/stdlib/uri/generic.rb +1599 -0
- data/runtime/stdlib/uri/http.rb +106 -0
- data/runtime/stdlib/uri/https.rb +22 -0
- data/runtime/stdlib/uri/ldap.rb +260 -0
- data/runtime/stdlib/uri/ldaps.rb +20 -0
- data/runtime/stdlib/uri/mailto.rb +280 -0
- data/spec/builder/build_source_spec.rb +52 -0
- data/spec/builder/fixtures/build_source/adam.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
- data/spec/builder/fixtures/build_source/beynon.rb +0 -0
- data/spec/builder/fixtures/build_source/charles.js +0 -0
- data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/x.js +0 -0
- data/spec/builder/fixtures/build_source/foo/y.js +0 -0
- data/spec/builder/output_path_spec.rb +50 -0
- data/spec/grammar/alias_spec.rb +26 -0
- data/spec/grammar/and_spec.rb +13 -0
- data/spec/grammar/array_spec.rb +22 -0
- data/spec/grammar/attrasgn_spec.rb +28 -0
- data/spec/grammar/begin_spec.rb +38 -0
- data/spec/grammar/block_spec.rb +12 -0
- data/spec/grammar/break_spec.rb +17 -0
- data/spec/grammar/call_spec.rb +58 -0
- data/spec/grammar/class_spec.rb +35 -0
- data/spec/grammar/const_spec.rb +13 -0
- data/spec/grammar/cvar_spec.rb +11 -0
- data/spec/grammar/def_spec.rb +60 -0
- data/spec/grammar/false_spec.rb +17 -0
- data/spec/grammar/file_spec.rb +7 -0
- data/spec/grammar/gvar_spec.rb +13 -0
- data/spec/grammar/hash_spec.rb +17 -0
- data/spec/grammar/iasgn_spec.rb +9 -0
- data/spec/grammar/if_spec.rb +26 -0
- data/spec/grammar/iter_spec.rb +59 -0
- data/spec/grammar/ivar_spec.rb +9 -0
- data/spec/grammar/lasgn_spec.rb +8 -0
- data/spec/grammar/line_spec.rb +8 -0
- data/spec/grammar/lvar_spec.rb +38 -0
- data/spec/grammar/module_spec.rb +27 -0
- data/spec/grammar/nil_spec.rb +17 -0
- data/spec/grammar/not_spec.rb +27 -0
- data/spec/grammar/op_asgn1_spec.rb +23 -0
- data/spec/grammar/op_asgn2_spec.rb +23 -0
- data/spec/grammar/or_spec.rb +13 -0
- data/spec/grammar/return_spec.rb +17 -0
- data/spec/grammar/sclass_spec.rb +20 -0
- data/spec/grammar/self_spec.rb +17 -0
- data/spec/grammar/str_spec.rb +96 -0
- data/spec/grammar/super_spec.rb +20 -0
- data/spec/grammar/true_spec.rb +17 -0
- data/spec/grammar/undef_spec.rb +15 -0
- data/spec/grammar/unless_spec.rb +13 -0
- data/spec/grammar/while_spec.rb +15 -0
- data/spec/grammar/xstr_spec.rb +116 -0
- data/spec/grammar/yield_spec.rb +20 -0
- data/spec/spec_helper.rb +9 -0
- metadata +346 -21
- data/lib/opal/bundle.rb +0 -34
- data/lib/opal/lexer.rb +0 -902
- data/lib/opal/nodes.rb +0 -2150
- data/lib/opal/parser.rb +0 -4894
- data/lib/opal/rake/bundle_task.rb +0 -63
- data/opal-parser.js +0 -8343
- data/stdlib/strscan.rb +0 -52
- data/templates/init/Rakefile +0 -7
- data/templates/init/index.html +0 -17
- data/templates/init/lib/__NAME__.rb +0 -2
data/lib/opal.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'opal/parser/parser'
|
2
|
+
require 'opal/builder'
|
3
|
+
require 'opal/dependency_builder'
|
4
|
+
require 'opal/context'
|
5
|
+
require 'opal/version'
|
5
6
|
|
6
|
-
# Opal is a set of build tools and runtime utilies for compiling ruby
|
7
|
-
# source code into javascript. Opal can use therubyracer to provide a
|
8
|
-
# ruby context for evaluating the generated javascript against the
|
9
|
-
# provided runtime.
|
10
7
|
module Opal
|
11
|
-
|
12
|
-
|
8
|
+
def self.opal_dir
|
9
|
+
File.expand_path '../..', __FILE__
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
12
|
+
def self.runtime_code
|
13
|
+
File.read File.join(opal_dir, 'opal.js')
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
def self.runtime_debug_code
|
17
|
+
File.read File.join(opal_dir, 'opal.debug.js')
|
18
|
+
end
|
19
19
|
end
|
20
|
-
|
data/lib/opal/builder.rb
CHANGED
@@ -1,177 +1,75 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'opal/parser'
|
3
|
-
require 'opal/version'
|
4
2
|
|
5
3
|
module Opal
|
6
|
-
# The Builder class is used for building single ruby sources, or
|
7
|
-
# building the core library ready for the browser/v8 context. It
|
8
|
-
# is not used directly for building gem.
|
9
4
|
class Builder
|
5
|
+
def initialize(sources, options = {})
|
6
|
+
@sources = Array(sources)
|
7
|
+
@options = options
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
STDLIB_PATH = File.join OPAL_PATH, 'stdlib'
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@parser = Parser.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def parse(source, options = {})
|
20
|
-
@parser.parse source, options
|
21
|
-
end
|
22
|
-
|
23
|
-
# Returns the result of the compiled file ready for opal to load.
|
24
|
-
#
|
25
|
-
# `relative_path` is used for the name the built file should have.
|
26
|
-
# This is used for building a singular rb or js file into the
|
27
|
-
# compiled output, and will avoid the user's dir setup being exposed
|
28
|
-
# in production code. It will be of the form
|
29
|
-
# `lib/some_lib/some_lib.rb`
|
30
|
-
#
|
31
|
-
# @param [String] full_path The full pathname to the file to build
|
32
|
-
# @paeam [String] relative_path The pathname to be used in the build
|
33
|
-
# file.
|
34
|
-
#
|
35
|
-
# @return [String]
|
36
|
-
def wrap_source(full_path, relative_path = nil)
|
37
|
-
relative_path ||= full_path
|
38
|
-
ext = File.extname full_path
|
39
|
-
# relative_path = relative_path.sub(/\.rb/, '.js') if ext == '.rb'
|
40
|
-
content = compile_source full_path
|
41
|
-
|
42
|
-
"opal.lib('#{relative_path}', #{content});\n"
|
9
|
+
@options[:out] = '.' if @options[:out] == '' or !@options[:out]
|
43
10
|
end
|
44
11
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
#
|
49
|
-
# @param [String] full_path location of the source to build
|
50
|
-
# @return [String] compiled source
|
51
|
-
def compile_source(full_path)
|
52
|
-
ext = File.extname full_path
|
53
|
-
src = File.read full_path
|
12
|
+
def build
|
13
|
+
@parser = Parser.new @options
|
14
|
+
@factories = {}
|
54
15
|
|
55
|
-
|
56
|
-
when '.js'
|
57
|
-
"function($rb, self, __FILE__) { #{src} }"
|
16
|
+
@sources.each { |s| build_source '.', s }
|
58
17
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
else
|
63
|
-
raise "Bad file type for wrapping. Must be ruby or javascript"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Build the given sources from the standard library. These can be
|
68
|
-
# globs. Returns a string of all content.
|
69
|
-
def build_stdlib(*files)
|
70
|
-
code = []
|
71
|
-
Dir.chdir(STDLIB_PATH) do
|
72
|
-
files.each do |file|
|
73
|
-
lib = Dir[file + '.rb']
|
74
|
-
full_path = File.join STDLIB_PATH, lib.first
|
75
|
-
code << wrap_source(full_path, file)
|
18
|
+
if @options[:join]
|
19
|
+
File.open(@options[:join], 'w+') do |o|
|
20
|
+
@factories.each { |path, factory| o.write factory }
|
76
21
|
end
|
77
22
|
end
|
78
|
-
|
79
|
-
code.join ''
|
80
23
|
end
|
81
24
|
|
82
|
-
|
83
|
-
|
84
|
-
# :project_dir - The base directory to work in. If not given then cwd is used.
|
85
|
-
#
|
86
|
-
# :files - May be a single source, a directory, or an array of ruby/js src
|
87
|
-
#
|
88
|
-
# :out - The output file. All sources are built into a single output file.
|
89
|
-
# If this is not given, it will default to project_dir/javascripts/name.js
|
90
|
-
# where name is the basename of the given project_dir or cwd.
|
91
|
-
#
|
92
|
-
# :main - only useful when more than one input is given to determine which
|
93
|
-
# file is automatically loaded on running in the browser.
|
94
|
-
#
|
95
|
-
# :watch - watch all sources and automatically recompile if one changes
|
96
|
-
#
|
97
|
-
# :pre - pre content to add. Could be copyright, or extra code etc
|
98
|
-
#
|
99
|
-
# :post - post content.. could be extra code etc
|
100
|
-
#
|
101
|
-
# Also, if no output is given, then one file will be used for all sources,
|
102
|
-
# and the files name will be taken as the basename of the root_dir/cwd.
|
103
|
-
#
|
104
|
-
# @param {Hash} options Build options to use
|
105
|
-
def build(options = {})
|
106
|
-
files = options[:files] || []
|
107
|
-
files = [files] unless files.is_a? Array
|
108
|
-
options[:files] = files = Dir.[](*files)
|
109
|
-
|
110
|
-
raise "Opal::Builder - No input files could be found" if files.empty?
|
25
|
+
def build_source(base, source)
|
26
|
+
path = base == '.' ? source : File.join(base, source)
|
111
27
|
|
112
|
-
|
28
|
+
if File.directory? path
|
29
|
+
Dir.entries(path).each do |e|
|
30
|
+
next if e == '.' or e == '..'
|
31
|
+
build_source path, e
|
32
|
+
end
|
113
33
|
|
114
|
-
|
115
|
-
|
116
|
-
elsif main
|
117
|
-
raise "Opal::Builder - Main file does not exist!" unless File.exists? main
|
118
|
-
files << main unless files.include? main
|
119
|
-
elsif main == false
|
120
|
-
options[:main] = false
|
121
|
-
else
|
122
|
-
options[:main] = files.first
|
34
|
+
elsif File.extname(path) == '.rb'
|
35
|
+
build_file base, source
|
123
36
|
end
|
37
|
+
end
|
124
38
|
|
125
|
-
|
39
|
+
def build_file(base, source)
|
40
|
+
path = base == '.' ? source : File.join(base, source)
|
41
|
+
code = @parser.parse File.read(path), path
|
126
42
|
|
127
|
-
|
128
|
-
|
43
|
+
if /^lib/ =~ path
|
44
|
+
code = "opal.lib('#{path[4..-4]}', function() {\n#{code}\n});\n"
|
45
|
+
else
|
46
|
+
code = "opal.file('/#{path}', function() {\n#{code}\n});\n"
|
129
47
|
end
|
130
48
|
|
131
|
-
|
49
|
+
if @options[:join]
|
50
|
+
@factories[path] = code
|
51
|
+
elsif @options[:out]
|
52
|
+
out = output_path base, source
|
132
53
|
|
133
|
-
|
134
|
-
|
135
|
-
puts "Watching for changes.."
|
136
|
-
loop do
|
137
|
-
out_mtime = File.stat(options[:out]).mtime
|
138
|
-
options[:files].each do |file|
|
139
|
-
if File.stat(file).mtime > out_mtime
|
140
|
-
puts "#{Time.now} rebuilding - changes detected in #{file}"
|
141
|
-
rebuild options
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
begin
|
146
|
-
sleep 1
|
147
|
-
rescue Interrupt
|
148
|
-
exit 0
|
149
|
-
end
|
150
|
-
end
|
54
|
+
FileUtils.mkdir_p File.dirname(out)
|
55
|
+
File.open(out, 'w+') { |o| o.write code }
|
151
56
|
end
|
152
57
|
end
|
153
58
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
if options[:main]
|
168
|
-
main = options[:main].sub(/\.rb$/, '')
|
169
|
-
out.write "opal.require('#{main}');\n"
|
59
|
+
def output_path(base, source)
|
60
|
+
fname = source.chomp('.rb') + '.js'
|
61
|
+
if @options[:out] == '.'
|
62
|
+
base == '.' ? fname : File.join(base, fname)
|
63
|
+
else
|
64
|
+
if base == '.'
|
65
|
+
File.join @options[:out], fname
|
66
|
+
else
|
67
|
+
parts = base.split '/'
|
68
|
+
parts[0] = @options[:out]
|
69
|
+
parts << fname
|
70
|
+
File.join *parts
|
170
71
|
end
|
171
|
-
|
172
|
-
# out.write @post if @post
|
173
72
|
end
|
174
73
|
end
|
175
74
|
end
|
176
75
|
end
|
177
|
-
|
data/lib/opal/command.rb
CHANGED
@@ -1,143 +1,73 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'opal/builder'
|
4
|
+
require 'opal/version'
|
4
5
|
|
5
6
|
module Opal
|
6
|
-
# Command runner. When using the `opal` bin file, this class is used to
|
7
|
-
# delegate commands based on the options passed from the command line.
|
8
7
|
class Command
|
9
8
|
|
10
|
-
# Valid command line arguments
|
11
|
-
COMMANDS = [:help, :irb, :compile, :bundle, :exec, :eval, :install, :init]
|
12
|
-
|
13
9
|
def initialize(args)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
elsif command and File.exists? command
|
19
|
-
eval command
|
20
|
-
else
|
21
|
-
help
|
10
|
+
options = {}
|
11
|
+
if ARGV.first == 'init'
|
12
|
+
options[:init] = true
|
13
|
+
ARGV.shift
|
22
14
|
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Initialize a project either in current directory, or directory
|
26
|
-
# specified in ARGV.
|
27
|
-
def init
|
28
|
-
path = File.expand_path(ARGV.first || Dir.getwd)
|
29
|
-
base = File.basename(path)
|
30
|
-
template = File.join(OPAL_DIR, "templates", "init")
|
31
|
-
|
32
|
-
Dir.chdir(template) do
|
33
|
-
Dir["**/*"].each do |f|
|
34
|
-
next if File.directory? f
|
35
|
-
|
36
|
-
full = File.expand_path f, template
|
37
|
-
dest = File.join path, f.sub(/__NAME__/, base)
|
38
15
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
FileUtils.mkdir_p File.dirname(dest)
|
45
|
-
|
46
|
-
File.open(dest, 'w+') do |o|
|
47
|
-
o.write File.read(full).gsub(/__NAME__/, base)
|
48
|
-
end
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.on('-c', '--compile', 'Compile ruby') do |c|
|
18
|
+
options[:compile] = c
|
49
19
|
end
|
50
|
-
end
|
51
20
|
|
52
|
-
|
53
|
-
|
54
|
-
%w[opal.js opal-parser.js].each do |src|
|
55
|
-
File.open(File.join(path, "js", src), "w+") do |o|
|
56
|
-
o.write File.read(File.join(OPAL_DIR, src))
|
21
|
+
opts.on('-o', '--out [DIR]', 'Output directory') do |o|
|
22
|
+
options[:out] = o || ''
|
57
23
|
end
|
58
|
-
end
|
59
|
-
end
|
60
24
|
|
61
|
-
|
62
|
-
|
63
|
-
|
25
|
+
opts.on('-j', '--join [OUT]', 'Join out') do |j|
|
26
|
+
options[:join] = j || ''
|
27
|
+
end
|
64
28
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
ctx = Context.new :method_missing => true,
|
69
|
-
:overload_arithmetic => true,
|
70
|
-
:overload_comparison => true,
|
71
|
-
:overload_bitwise => true
|
72
|
-
ctx.start_repl
|
73
|
-
end
|
29
|
+
opts.on('-d', '--debug', 'Debug mode') do |d|
|
30
|
+
options[:debug] = true
|
31
|
+
end
|
74
32
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
#
|
81
|
-
# Usage:
|
82
|
-
#
|
83
|
-
# opal eval path/to/some/file.rb
|
84
|
-
# # => "some result"
|
85
|
-
#
|
86
|
-
# opal eval "1.class"
|
87
|
-
# # => Numeric
|
88
|
-
#
|
89
|
-
# @param [String] code path or ruby code to eval
|
90
|
-
def eval(code = nil, *)
|
91
|
-
abort "Usage: opal eval [Ruby code or file path]" unless code
|
33
|
+
opts.on_tail("-v", "--version", "Show version") do
|
34
|
+
puts Opal::VERSION
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
end.parse!
|
92
38
|
|
93
|
-
if
|
94
|
-
|
39
|
+
if options[:init]
|
40
|
+
init options
|
41
|
+
elsif options[:compile]
|
42
|
+
build options
|
43
|
+
else
|
44
|
+
run options
|
95
45
|
end
|
96
|
-
|
97
|
-
context = Context.new :method_missing => true,
|
98
|
-
:overload_arithmetic => true,
|
99
|
-
:overload_comparison => true,
|
100
|
-
:overload_bitwise => true
|
101
|
-
|
102
|
-
puts context.eval code
|
103
46
|
end
|
104
47
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
#
|
111
|
-
# Usage:
|
112
|
-
#
|
113
|
-
# opal compile path/to/ruby.rb
|
114
|
-
# # => "generated code"
|
115
|
-
#
|
116
|
-
# opal compile "some ruby code"
|
117
|
-
# # => generated code
|
118
|
-
#
|
119
|
-
# @param [String] path file path or ruby code
|
120
|
-
def compile(path = nil, *)
|
121
|
-
abort "Usage: opal compile [Ruby code or file path]" unless path
|
122
|
-
|
123
|
-
if File.exists? path
|
124
|
-
puts Parser.new.parse File.read(path)
|
48
|
+
def run(options)
|
49
|
+
if ARGV.empty?
|
50
|
+
Context.new.start_repl
|
51
|
+
elsif File.exists? ARGV.first
|
52
|
+
Context.runner ARGV.first
|
125
53
|
else
|
126
|
-
puts
|
54
|
+
puts "#{ARGV.first} does not exist"
|
127
55
|
end
|
128
56
|
end
|
129
57
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
58
|
+
def init(options)
|
59
|
+
out = options[:out]
|
60
|
+
src = options[:debug] ? Opal.runtime_debug_code : Opal.runtime_code
|
61
|
+
out ||= (options[:debug] ? 'opal.debug.js' : 'opal.js')
|
134
62
|
|
135
|
-
|
136
|
-
|
137
|
-
bundle = Bundle.new package
|
63
|
+
FileUtils.mkdir_p File.dirname(out)
|
64
|
+
File.open(out, 'w+') { |o| o.write src }
|
138
65
|
|
139
|
-
puts
|
66
|
+
puts "Wrote Opal to #{out}#{options[:debug] && ' (debug)'}"
|
140
67
|
end
|
141
|
-
end
|
142
|
-
end
|
143
68
|
|
69
|
+
def build(options)
|
70
|
+
Builder.new(ARGV, options).build
|
71
|
+
end
|
72
|
+
end # Command
|
73
|
+
end
|
data/lib/opal/context.rb
CHANGED
@@ -1,30 +1,38 @@
|
|
1
|
+
require 'opal/environment'
|
2
|
+
|
1
3
|
module Opal
|
2
4
|
class Context
|
3
|
-
# Options are mainly just passed onto the builder/parser.
|
4
|
-
def initialize(options = {})
|
5
|
-
@options = options
|
6
|
-
@root_dir = options[:dir] || Dir.getwd
|
7
|
-
@builder = Opal::Builder.new
|
8
|
-
@loaded_paths = false
|
9
5
|
|
10
|
-
|
11
|
-
|
6
|
+
attr_reader :v8
|
7
|
+
attr_reader :parser
|
8
|
+
attr_reader :environment
|
12
9
|
|
13
10
|
##
|
14
|
-
#
|
15
|
-
# passes the require through to the underlying context.
|
11
|
+
# Glob may be a file or glob path, as a string.
|
16
12
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
def self.runner(glob)
|
14
|
+
ctx = self.new
|
15
|
+
ctx.v8['opal_tmp_glob'] = Dir[glob]
|
16
|
+
|
17
|
+
runner = <<-CODE
|
18
|
+
files = `opal_tmp_glob`
|
19
|
+
|
20
|
+
files.each do |a|
|
21
|
+
require a
|
22
|
+
end
|
23
|
+
CODE
|
24
|
+
|
25
|
+
ctx.eval_irb runner, '(runner)'
|
26
|
+
ctx.finish
|
21
27
|
end
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@
|
29
|
+
def initialize root = Dir.getwd
|
30
|
+
@environment = Environment.load root
|
31
|
+
@root = root
|
32
|
+
@parser = Opal::Parser.new :debug => true
|
33
|
+
@loaded_paths = false
|
34
|
+
|
35
|
+
setup_v8
|
28
36
|
end
|
29
37
|
|
30
38
|
# Start normal js repl
|
@@ -42,18 +50,33 @@ module Opal
|
|
42
50
|
break
|
43
51
|
end
|
44
52
|
|
45
|
-
puts "=> #{
|
53
|
+
puts "=> #{eval_irb line, '(irb)'}"
|
46
54
|
end
|
47
55
|
|
48
56
|
finish
|
49
57
|
end
|
50
58
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
def eval_builder(content, file)
|
60
|
+
@parser.parse content, file
|
61
|
+
end
|
62
|
+
|
63
|
+
def eval(content, file = "(irb)", line = "")
|
64
|
+
@v8.eval eval_builder(content, file), file
|
65
|
+
end
|
66
|
+
|
67
|
+
def eval_irb(content, file = '(irb)')
|
68
|
+
code = <<-CODE
|
69
|
+
(function() { try {
|
70
|
+
opal.FILE = '#{file}';
|
71
|
+
var res = #{ eval_builder content, file };
|
72
|
+
return res.m$inspect();
|
73
|
+
}
|
74
|
+
catch (e) {
|
75
|
+
opal.bt(e);
|
76
|
+
return "nil";
|
77
|
+
}
|
78
|
+
})()
|
79
|
+
CODE
|
57
80
|
|
58
81
|
@v8.eval code, file
|
59
82
|
end
|
@@ -64,7 +87,7 @@ module Opal
|
|
64
87
|
# #setup_v8
|
65
88
|
def finish
|
66
89
|
return unless @v8
|
67
|
-
@v8.eval "opal.
|
90
|
+
@v8.eval "opal.do_at_exit()", "(irb)"
|
68
91
|
|
69
92
|
@v8 = nil
|
70
93
|
end
|
@@ -83,13 +106,30 @@ module Opal
|
|
83
106
|
|
84
107
|
@v8 = V8::Context.new
|
85
108
|
@v8['console'] = Console.new
|
109
|
+
@v8['opal_filesystem'] = FileSystem.new(self)
|
110
|
+
|
111
|
+
load_runtime
|
112
|
+
load_gem_runtime
|
113
|
+
end
|
86
114
|
|
87
|
-
|
88
|
-
|
89
|
-
|
115
|
+
##
|
116
|
+
# Loads the runtime from build/*.js. This isnt included in the git repo,
|
117
|
+
# so needs to be built before running (gems should have these files included)
|
118
|
+
|
119
|
+
def load_runtime
|
120
|
+
@v8.eval Opal.runtime_debug_code, '(runtime)'
|
121
|
+
end
|
90
122
|
|
91
|
-
|
92
|
-
|
123
|
+
##
|
124
|
+
# Load gem specific runtime.
|
125
|
+
|
126
|
+
def load_gem_runtime
|
127
|
+
dir = File.join Opal.opal_dir, 'runtime', 'gemlib'
|
128
|
+
order = File.read(File.join dir, 'load_order').strip.split("\n")
|
129
|
+
order.each do |f|
|
130
|
+
path = File.join dir, "#{f}.rb"
|
131
|
+
eval File.read(path), path
|
132
|
+
end
|
93
133
|
end
|
94
134
|
|
95
135
|
##
|
@@ -110,78 +150,99 @@ module Opal
|
|
110
150
|
|
111
151
|
class FileSystem
|
112
152
|
|
113
|
-
def initialize
|
114
|
-
@context
|
153
|
+
def initialize context
|
154
|
+
@context = context
|
155
|
+
@environment = context.environment
|
156
|
+
@cache = {}
|
115
157
|
end
|
116
158
|
|
117
|
-
|
118
|
-
|
119
|
-
end
|
159
|
+
##
|
160
|
+
# Used to bootstrap loadpaths.
|
120
161
|
|
121
|
-
def
|
122
|
-
|
123
|
-
end
|
162
|
+
def find_paths
|
163
|
+
return @paths if @paths
|
124
164
|
|
125
|
-
|
126
|
-
File.exist? path
|
127
|
-
end
|
165
|
+
paths = [File.join(Opal.opal_dir, 'runtime', 'stdlib')]
|
128
166
|
|
129
|
-
|
130
|
-
|
131
|
-
|
167
|
+
@environment.require_paths.each do |p|
|
168
|
+
paths << File.join(@environment.root, p)
|
169
|
+
end
|
132
170
|
|
133
|
-
|
134
|
-
|
135
|
-
|
171
|
+
@environment.specs.each do |spec|
|
172
|
+
paths.push *spec.load_paths
|
173
|
+
end
|
136
174
|
|
137
|
-
|
138
|
-
File.join *parts
|
175
|
+
@paths = @context.v8.eval paths.inspect
|
139
176
|
end
|
140
|
-
end
|
141
177
|
|
142
|
-
|
143
|
-
|
178
|
+
##
|
179
|
+
# Require a file from context
|
144
180
|
|
145
|
-
|
181
|
+
def require path, paths
|
182
|
+
resolved = find_lib path, paths
|
146
183
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
184
|
+
return nil unless resolved
|
185
|
+
|
186
|
+
return false if @cache[resolved]
|
151
187
|
|
152
|
-
|
153
|
-
|
154
|
-
|
188
|
+
@cache[resolved] = true
|
189
|
+
@context.v8.eval "opal.FILE = '#{resolved}'"
|
190
|
+
@context.eval File.read(resolved), resolved
|
155
191
|
|
156
|
-
|
192
|
+
true
|
157
193
|
end
|
158
194
|
|
159
|
-
def find_lib
|
160
|
-
|
161
|
-
candidate = File.join
|
195
|
+
def find_lib path, paths
|
196
|
+
paths.each do |l|
|
197
|
+
candidate = File.join l, "#{path}.rb"
|
162
198
|
return candidate if File.exists? candidate
|
163
199
|
|
164
|
-
candidate = File.join
|
200
|
+
candidate = File.join l, path
|
165
201
|
return candidate if File.exists? candidate
|
166
|
-
end
|
167
202
|
|
168
|
-
|
169
|
-
|
203
|
+
candidate = File.expand_path path
|
204
|
+
return candidate if File.exists? candidate
|
205
|
+
|
206
|
+
candidate = File.expand_path("#{path}.rb")
|
207
|
+
return candidate if File.exists? candidate
|
208
|
+
end
|
170
209
|
|
171
210
|
nil
|
172
211
|
end
|
173
212
|
|
174
|
-
|
175
|
-
|
213
|
+
##
|
214
|
+
# Build body for given ruby file. Should return a function
|
215
|
+
# capable of being executed by opal of form:
|
216
|
+
#
|
217
|
+
# function(self, FILE) { ... }
|
218
|
+
|
219
|
+
def file_body(path)
|
220
|
+
@context.eval File.read(path), path
|
176
221
|
end
|
177
222
|
|
178
|
-
def
|
179
|
-
|
180
|
-
@context.eval code, filename
|
181
|
-
# code
|
223
|
+
def cwd
|
224
|
+
Dir.getwd
|
182
225
|
end
|
183
|
-
end
|
184
226
|
|
227
|
+
def glob(*arr)
|
228
|
+
Dir.glob arr
|
229
|
+
end
|
230
|
+
|
231
|
+
def exist_p(path)
|
232
|
+
File.exist? path
|
233
|
+
end
|
234
|
+
|
235
|
+
def expand_path(filename, dir_string = nil)
|
236
|
+
File.expand_path filename, dir_string
|
237
|
+
end
|
238
|
+
|
239
|
+
def dirname(file)
|
240
|
+
File.dirname file
|
241
|
+
end
|
242
|
+
|
243
|
+
def join(*parts)
|
244
|
+
File.join *parts
|
245
|
+
end
|
246
|
+
end # FileSystem
|
185
247
|
end
|
186
248
|
end
|
187
|
-
|