opal 0.3.11 → 0.3.15
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.
- 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
|
-
|