opal 0.3.15 → 0.3.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. data/.gitignore +1 -1
  2. data/Gemfile +8 -2
  3. data/README.md +1 -1
  4. data/Rakefile +51 -57
  5. data/bin/opal +50 -2
  6. data/{runtime/corelib → core}/alpha.rb +6 -1
  7. data/{runtime/corelib → core}/array.rb +38 -42
  8. data/{runtime/corelib → core}/basic_object.rb +6 -17
  9. data/core/boolean.rb +40 -0
  10. data/core/class.rb +69 -0
  11. data/{runtime/corelib → core}/comparable.rb +0 -0
  12. data/core/debug.js +59 -0
  13. data/core/debug.rb +35 -0
  14. data/core/dir.rb +90 -0
  15. data/core/enumerable.rb +331 -0
  16. data/core/enumerator.rb +126 -0
  17. data/core/error.rb +40 -0
  18. data/{runtime/corelib → core}/file.rb +6 -3
  19. data/core/gemlib.rb +30 -0
  20. data/{runtime/corelib → core}/hash.rb +37 -35
  21. data/{runtime/corelib → core}/io.rb +0 -0
  22. data/{runtime/corelib → core}/kernel.rb +26 -21
  23. data/{runtime/corelib → core}/load_order +2 -5
  24. data/{runtime/corelib → core}/match_data.rb +2 -4
  25. data/core/module.rb +204 -0
  26. data/{runtime/corelib → core}/nil_class.rb +1 -7
  27. data/{runtime/corelib → core}/numeric.rb +9 -13
  28. data/core/object.rb +17 -0
  29. data/{runtime/corelib → core}/proc.rb +2 -13
  30. data/{runtime/corelib → core}/range.rb +19 -7
  31. data/{runtime/corelib → core}/rational.rb +0 -0
  32. data/{runtime/corelib → core}/regexp.rb +2 -6
  33. data/core/runtime.js +672 -0
  34. data/{runtime/corelib → core}/string.rb +25 -9
  35. data/{runtime/corelib → core}/struct.rb +0 -0
  36. data/core/time.rb +111 -0
  37. data/{runtime/corelib → core}/top_self.rb +0 -0
  38. data/{runtime/spec → core_spec}/README.md +0 -0
  39. data/{runtime/spec → core_spec}/core/array/allocate_spec.rb +0 -0
  40. data/{runtime/spec → core_spec}/core/array/append_spec.rb +0 -0
  41. data/{runtime/spec → core_spec}/core/array/assoc_spec.rb +0 -0
  42. data/{runtime/spec → core_spec}/core/array/at_spec.rb +0 -0
  43. data/{runtime/spec → core_spec}/core/array/clear_spec.rb +0 -0
  44. data/{runtime/spec → core_spec}/core/array/collect_spec.rb +0 -0
  45. data/{runtime/spec → core_spec}/core/array/compact_spec.rb +0 -0
  46. data/{runtime/spec → core_spec}/core/array/concat_spec.rb +0 -0
  47. data/{runtime/spec → core_spec}/core/array/constructor_spec.rb +0 -0
  48. data/{runtime/spec → core_spec}/core/array/count_spec.rb +0 -0
  49. data/{runtime/spec → core_spec}/core/array/delete_at_spec.rb +0 -0
  50. data/{runtime/spec → core_spec}/core/array/delete_if_spec.rb +0 -0
  51. data/{runtime/spec → core_spec}/core/array/delete_spec.rb +0 -0
  52. data/{runtime/spec → core_spec}/core/array/each_index_spec.rb +0 -0
  53. data/{runtime/spec → core_spec}/core/array/each_spec.rb +0 -0
  54. data/{runtime/spec → core_spec}/core/array/element_reference_spec.rb +0 -0
  55. data/{runtime/spec → core_spec}/core/array/element_set_spec.rb +0 -0
  56. data/{runtime/spec → core_spec}/core/array/empty_spec.rb +0 -0
  57. data/{runtime/spec → core_spec}/core/array/eql_spec.rb +0 -0
  58. data/{runtime/spec → core_spec}/core/array/equal_value_spec.rb +0 -0
  59. data/{runtime/spec → core_spec}/core/array/fetch_spec.rb +0 -0
  60. data/{runtime/spec → core_spec}/core/array/first_spec.rb +0 -0
  61. data/{runtime/spec → core_spec}/core/array/fixtures/classes.rb +0 -0
  62. data/{runtime/spec → core_spec}/core/array/flatten_spec.rb +0 -0
  63. data/{runtime/spec → core_spec}/core/array/include_spec.rb +0 -0
  64. data/{runtime/spec → core_spec}/core/array/insert_spec.rb +0 -0
  65. data/{runtime/spec → core_spec}/core/array/last_spec.rb +0 -0
  66. data/{runtime/spec → core_spec}/core/array/length_spec.rb +0 -0
  67. data/{runtime/spec → core_spec}/core/array/map_spec.rb +0 -0
  68. data/{runtime/spec → core_spec}/core/array/plus_spec.rb +0 -0
  69. data/{runtime/spec → core_spec}/core/array/pop_spec.rb +0 -0
  70. data/{runtime/spec → core_spec}/core/array/push_spec.rb +0 -0
  71. data/{runtime/spec → core_spec}/core/array/rassoc_spec.rb +0 -0
  72. data/{runtime/spec → core_spec}/core/array/reject_spec.rb +0 -0
  73. data/{runtime/spec → core_spec}/core/array/replace_spec.rb +0 -0
  74. data/{runtime/spec → core_spec}/core/array/reverse_each_spec.rb +0 -0
  75. data/{runtime/spec → core_spec}/core/array/reverse_spec.rb +0 -0
  76. data/{runtime/spec → core_spec}/core/array/shared/collect.rb +0 -0
  77. data/{runtime/spec → core_spec}/core/array/shared/eql.rb +0 -0
  78. data/{runtime/spec → core_spec}/core/array/shared/length.rb +0 -0
  79. data/{runtime/spec → core_spec}/core/array/shared/replace.rb +0 -0
  80. data/{runtime/spec → core_spec}/core/class/new_spec.rb +0 -0
  81. data/{runtime/spec → core_spec}/core/enumerable/all_spec.rb +0 -0
  82. data/{runtime/spec → core_spec}/core/enumerable/any_spec.rb +0 -0
  83. data/{runtime/spec → core_spec}/core/enumerable/collect_spec.rb +0 -0
  84. data/{runtime/spec → core_spec}/core/enumerable/count_spec.rb +0 -0
  85. data/{runtime/spec → core_spec}/core/enumerable/detect_spec.rb +0 -0
  86. data/{runtime/spec → core_spec}/core/enumerable/find_spec.rb +0 -0
  87. data/core_spec/core/enumerable/first_spec.rb +3 -0
  88. data/{runtime/spec → core_spec}/core/enumerable/fixtures/classes.rb +0 -0
  89. data/{runtime/spec → core_spec}/core/enumerable/shared/collect.rb +0 -0
  90. data/{runtime/spec → core_spec}/core/enumerable/shared/entries.rb +0 -0
  91. data/{runtime/spec → core_spec}/core/enumerable/shared/find.rb +0 -0
  92. data/core_spec/core/enumerable/shared/take.rb +31 -0
  93. data/{runtime/spec → core_spec}/core/enumerable/to_a_spec.rb +0 -0
  94. data/{runtime/spec → core_spec}/core/false/and_spec.rb +0 -0
  95. data/{runtime/spec → core_spec}/core/false/inspect_spec.rb +0 -0
  96. data/{runtime/spec → core_spec}/core/false/or_spec.rb +0 -0
  97. data/{runtime/spec → core_spec}/core/false/to_s_spec.rb +0 -0
  98. data/{runtime/spec → core_spec}/core/false/xor_spec.rb +0 -0
  99. data/{runtime/spec → core_spec}/core/hash/allocate_spec.rb +0 -0
  100. data/{runtime/spec → core_spec}/core/hash/assoc_spec.rb +0 -0
  101. data/{runtime/spec → core_spec}/core/hash/clear_spec.rb +0 -0
  102. data/{runtime/spec → core_spec}/core/hash/clone_spec.rb +0 -0
  103. data/{runtime/spec → core_spec}/core/hash/default_spec.rb +0 -0
  104. data/{runtime/spec → core_spec}/core/hash/delete_if_spec.rb +0 -0
  105. data/{runtime/spec → core_spec}/core/hash/element_reference_spec.rb +0 -0
  106. data/{runtime/spec → core_spec}/core/hash/element_set_spec.rb +0 -0
  107. data/{runtime/spec → core_spec}/core/hash/new_spec.rb +0 -0
  108. data/{runtime/spec → core_spec}/core/matchdata/to_a_spec.rb +0 -0
  109. data/{runtime/spec → core_spec}/core/nil/and_spec.rb +0 -0
  110. data/{runtime/spec → core_spec}/core/nil/inspect_spec.rb +0 -0
  111. data/{runtime/spec → core_spec}/core/nil/nil_spec.rb +0 -0
  112. data/{runtime/spec → core_spec}/core/nil/or_spec.rb +0 -0
  113. data/{runtime/spec → core_spec}/core/nil/to_a_spec.rb +0 -0
  114. data/{runtime/spec → core_spec}/core/nil/to_f_spec.rb +0 -0
  115. data/{runtime/spec → core_spec}/core/nil/to_i_spec.rb +0 -0
  116. data/{runtime/spec → core_spec}/core/nil/to_s_spec.rb +0 -0
  117. data/{runtime/spec → core_spec}/core/nil/xor_spec.rb +0 -0
  118. data/{runtime/spec → core_spec}/core/numeric/equal_value_spec.rb +0 -0
  119. data/{runtime/spec → core_spec}/core/object/is_a_spec.rb +0 -0
  120. data/{runtime/spec → core_spec}/core/object/shared/kind_of.rb +0 -0
  121. data/{runtime/spec → core_spec}/core/regexp/match_spec.rb +0 -0
  122. data/{runtime/spec → core_spec}/core/regexp/shared/match.rb +0 -0
  123. data/{runtime/spec → core_spec}/core/symbol/to_proc_spec.rb +0 -0
  124. data/{runtime/spec → core_spec}/core/true/and_spec.rb +0 -0
  125. data/{runtime/spec → core_spec}/core/true/inspect_spec.rb +0 -0
  126. data/{runtime/spec → core_spec}/core/true/or_spec.rb +0 -0
  127. data/{runtime/spec → core_spec}/core/true/to_s_spec.rb +0 -0
  128. data/{runtime/spec → core_spec}/core/true/xor_spec.rb +0 -0
  129. data/{runtime/spec → core_spec}/language/alias_spec.rb +0 -0
  130. data/{runtime/spec → core_spec}/language/and_spec.rb +0 -0
  131. data/{runtime/spec → core_spec}/language/array_spec.rb +0 -0
  132. data/{runtime/spec → core_spec}/language/block_spec.rb +0 -0
  133. data/{runtime/spec → core_spec}/language/break_spec.rb +0 -0
  134. data/{runtime/spec → core_spec}/language/case_spec.rb +0 -0
  135. data/{runtime/spec → core_spec}/language/defined_spec.rb +0 -0
  136. data/{runtime/spec → core_spec}/language/ensure_spec.rb +0 -0
  137. data/{runtime/spec → core_spec}/language/fixtures/block.rb +0 -0
  138. data/{runtime/spec → core_spec}/language/fixtures/break.rb +0 -0
  139. data/{runtime/spec → core_spec}/language/fixtures/defined.rb +0 -0
  140. data/{runtime/spec → core_spec}/language/fixtures/ensure.rb +0 -0
  141. data/{runtime/spec → core_spec}/language/fixtures/next.rb +0 -0
  142. data/{runtime/spec → core_spec}/language/fixtures/send.rb +0 -0
  143. data/{runtime/spec → core_spec}/language/fixtures/super.rb +0 -0
  144. data/{runtime/spec → core_spec}/language/hash_spec.rb +0 -0
  145. data/{runtime/spec → core_spec}/language/if_spec.rb +0 -0
  146. data/{runtime/spec → core_spec}/language/loop_spec.rb +0 -0
  147. data/{runtime/spec → core_spec}/language/next_spec.rb +0 -0
  148. data/{runtime/spec → core_spec}/language/or_spec.rb +0 -0
  149. data/{runtime/spec → core_spec}/language/predefined_spec.rb +0 -0
  150. data/{runtime/spec → core_spec}/language/regexp/interpolation_spec.rb +8 -0
  151. data/{runtime/spec → core_spec}/language/regexp_spec.rb +0 -0
  152. data/{runtime/spec → core_spec}/language/send_spec.rb +0 -0
  153. data/{runtime/spec → core_spec}/language/string_spec.rb +0 -0
  154. data/{runtime/spec → core_spec}/language/super_spec.rb +0 -0
  155. data/{runtime/spec → core_spec}/language/symbol_spec.rb +0 -0
  156. data/{runtime/spec → core_spec}/language/undef_spec.rb +0 -0
  157. data/{runtime/spec → core_spec}/language/unless_spec.rb +0 -0
  158. data/{runtime/spec → core_spec}/language/until_spec.rb +0 -0
  159. data/core_spec/language/variables_spec.rb +112 -0
  160. data/{runtime/spec → core_spec}/language/versions/hash_1.9.rb +0 -0
  161. data/{runtime/spec → core_spec}/language/while_spec.rb +0 -0
  162. data/{runtime/spec → core_spec}/opal/opal/defined_spec.rb +0 -0
  163. data/{runtime/spec → core_spec}/opal/opal/function_spec.rb +0 -0
  164. data/{runtime/spec → core_spec}/opal/opal/native_spec.rb +0 -0
  165. data/{runtime/spec → core_spec}/opal/opal/null_spec.rb +0 -0
  166. data/{runtime/spec → core_spec}/opal/opal/number_spec.rb +0 -0
  167. data/{runtime/spec → core_spec}/opal/opal/object_spec.rb +0 -0
  168. data/{runtime/spec → core_spec}/opal/opal/string_spec.rb +0 -0
  169. data/{runtime/spec → core_spec}/opal/opal/typeof_spec.rb +0 -0
  170. data/{runtime/spec → core_spec}/opal/opal/undefined_spec.rb +0 -0
  171. data/{runtime/spec → core_spec}/opal/true/case_compare_spec.rb +0 -0
  172. data/{runtime/spec → core_spec}/opal/true/class_spec.rb +0 -0
  173. data/{docs/spec_runner.html → core_spec/release_runner.html} +4 -3
  174. data/core_spec/runner.html +16 -0
  175. data/core_spec/spec_helper.rb +23 -0
  176. data/lib/opal.rb +85 -2
  177. data/lib/opal/builder.rb +129 -46
  178. data/lib/opal/context.rb +47 -26
  179. data/lib/opal/dependency_builder.rb +113 -14
  180. data/lib/opal/environment.rb +40 -45
  181. data/lib/opal/parser/grammar.rb +2296 -2254
  182. data/lib/opal/parser/grammar.y +27 -8
  183. data/lib/opal/parser/lexer.rb +12 -3
  184. data/lib/opal/parser/parser.rb +117 -30
  185. data/lib/opal/parser/scope.rb +2 -2
  186. data/lib/opal/version.rb +1 -1
  187. data/opal.gemspec +3 -8
  188. data/spec/grammar/masgn_spec.rb +37 -0
  189. metadata +177 -227
  190. data/index.html +0 -434
  191. data/lib/opal/command.rb +0 -73
  192. data/runtime/README.md +0 -25
  193. data/runtime/corelib/boolean.rb +0 -44
  194. data/runtime/corelib/class.rb +0 -43
  195. data/runtime/corelib/complex.rb +0 -2
  196. data/runtime/corelib/dir.rb +0 -29
  197. data/runtime/corelib/enumerable.rb +0 -316
  198. data/runtime/corelib/enumerator.rb +0 -80
  199. data/runtime/corelib/error.rb +0 -25
  200. data/runtime/corelib/module.rb +0 -171
  201. data/runtime/corelib/native.rb +0 -50
  202. data/runtime/corelib/object.rb +0 -21
  203. data/runtime/corelib/time.rb +0 -196
  204. data/runtime/gemlib/alpha.rb +0 -5
  205. data/runtime/gemlib/kernel.rb +0 -17
  206. data/runtime/gemlib/load_order +0 -2
  207. data/runtime/kernel/class.js +0 -256
  208. data/runtime/kernel/debug.js +0 -42
  209. data/runtime/kernel/init.js +0 -114
  210. data/runtime/kernel/load_order +0 -5
  211. data/runtime/kernel/loader.js +0 -151
  212. data/runtime/kernel/runtime.js +0 -414
  213. data/runtime/spec/language/variables_spec.rb +0 -28
  214. data/runtime/spec/library/stringscanner/scan_spec.rb +0 -36
  215. data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +0 -49
  216. data/runtime/spec/spec_helper.rb +0 -25
  217. data/runtime/stdlib/base64.rb +0 -91
  218. data/runtime/stdlib/date.rb +0 -4
  219. data/runtime/stdlib/dev.rb +0 -171
  220. data/runtime/stdlib/forwardable.rb +0 -33
  221. data/runtime/stdlib/optparse.rb +0 -0
  222. data/runtime/stdlib/pp.rb +0 -6
  223. data/runtime/stdlib/racc/parser.rb +0 -159
  224. data/runtime/stdlib/rbconfig.rb +0 -0
  225. data/runtime/stdlib/si.rb +0 -17
  226. data/runtime/stdlib/strscan.rb +0 -53
  227. data/runtime/stdlib/uri.rb +0 -111
  228. data/runtime/stdlib/uri/common.rb +0 -1014
  229. data/runtime/stdlib/uri/ftp.rb +0 -261
  230. data/runtime/stdlib/uri/generic.rb +0 -1599
  231. data/runtime/stdlib/uri/http.rb +0 -106
  232. data/runtime/stdlib/uri/https.rb +0 -22
  233. data/runtime/stdlib/uri/ldap.rb +0 -260
  234. data/runtime/stdlib/uri/ldaps.rb +0 -20
  235. data/runtime/stdlib/uri/mailto.rb +0 -280
  236. data/spec/builder/output_path_spec.rb +0 -50
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -6,4 +6,12 @@ describe "Regexps with interpolation" do
6
6
  str = "foo|bar"
7
7
  /#{str}/.should == /foo|bar/
8
8
  end
9
+
10
+ it "allows interpolation to interact with other Regexp constructs" do
11
+ str = "foo)|(bar"
12
+ /(#{str})/.should == /(foo)|(bar)/
13
+
14
+ str = "a"
15
+ /[#{str}-z]/.should == /[a-z]/
16
+ end
9
17
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,112 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Basic assignment" do
4
+ it "allows the rhs to be assigned to the lhs" do
5
+ a = nil
6
+ a.should == nil
7
+ end
8
+
9
+ it "assigns nil to lhs when rhs is an empty expression" do
10
+ a = ()
11
+ a.should be_nil
12
+ end
13
+
14
+ it "assigns [] to lhs when rhs is an empty splat expression" do
15
+ a = *()
16
+ a.should == []
17
+ end
18
+
19
+ it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
20
+ a = *nil; a.should == []
21
+ a = *1; a.should == [1]
22
+ a = *[]; a.should == []
23
+ a = *[1]; a.should == [1]
24
+ a = *[nil]; a.should == [nil]
25
+ a = *[[]]; a.should == [[]]
26
+ a = *[1,2]; a.should == [1,2]
27
+ end
28
+ end
29
+
30
+ describe "Assigning multiple values" do
31
+ it "allows parallel assignment" do
32
+ a, b = 1, 2
33
+ a.should == 1
34
+ b.should == 2
35
+
36
+ a, = 1,2
37
+ a.should == 1
38
+ end
39
+
40
+ it "allows safe parallel swapping" do
41
+ a, b = 1, 2
42
+ a, b = b, a
43
+ a.should == 2
44
+ b.should == 1
45
+ end
46
+
47
+ it "bundles remaining values to an array when using the splat operator" do
48
+ a, *b = 1, 2, 3
49
+ a.should == 1
50
+ b.should == [2, 3]
51
+
52
+ *a = 1, 2, 3
53
+ a.should == [1, 2, 3]
54
+
55
+ *a = 4
56
+ a.should == [4]
57
+
58
+ *a = nil
59
+ a.should == [nil]
60
+
61
+ a, = *[1]
62
+ a.should == 1
63
+ end
64
+ end
65
+
66
+ describe "Single assignment" do
67
+ it "Assignment does not modify the lhs, it reassigns its reference" do
68
+ a = 'Foobar'
69
+ b = a
70
+ b = 'Bazquux'
71
+ a.should == 'Foobar'
72
+ b.should == 'Bazquux'
73
+ end
74
+
75
+ it "Assignment does not copy the object being assigned, just creates a new reference to it" do
76
+ a = []
77
+ b = a
78
+ b << 1
79
+ a.should == [1]
80
+ end
81
+
82
+ it "If rhs has multiple arguments, lhs becomes an Array of them" do
83
+ a = [1, 2, 3]
84
+ a.should == [1, 2, 3]
85
+
86
+ a = 1, (), 3
87
+ a.should == [1, nil, 3]
88
+ end
89
+ end
90
+
91
+ describe "Multiple assignment without grouping or splatting" do
92
+ it "An equal number of arguments on lhs and rhs assigns positionally" do
93
+ a, b, c, d = 1, 2, 3, 4
94
+ a.should == 1
95
+ b.should == 2
96
+ c.should == 3
97
+ d.should == 4
98
+ end
99
+
100
+ it "If rhs has too few arguments, the missing ones on lhs are assigned nil" do
101
+ a, b, c = 1, 2
102
+ a.should == 1
103
+ b.should == 2
104
+ c.should == nil
105
+ end
106
+
107
+ it "If rhs has too many arguments, the extra ones are silently not assigned anywhere" do
108
+ a, b = 1, 2, 3
109
+ a.should == 1
110
+ b.should == 2
111
+ end
112
+ end
File without changes
File without changes
File without changes
@@ -6,11 +6,12 @@
6
6
  <title>Opal Spec Runner</title>
7
7
  </head>
8
8
  <body>
9
- <script src="../opal.debug.js"></script>
9
+ <script src="../opal.js"></script>
10
10
  <script src="../opal-spec.js"></script>
11
- <script src="../opal.test.js"></script>
11
+ <script src="../core_spec.js"></script>
12
12
  <script>
13
- opal.main('/runtime/spec/spec_helper.rb');
13
+ opal.main('/core_spec/spec_helper.rb');
14
14
  </script>
15
15
  </body>
16
16
  </html>
17
+
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
5
+
6
+ <title>Opal Spec Runner</title>
7
+ </head>
8
+ <body>
9
+ <script src="../opal.debug.js"></script>
10
+ <script src="../opal-spec.debug.js"></script>
11
+ <script src="../core_spec.debug.js"></script>
12
+ <script>
13
+ opal.main('/core_spec/spec_helper.rb');
14
+ </script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,23 @@
1
+ # make sure these tests are indeed running inside opal, not any other
2
+ # ruby engine.
3
+ unless RUBY_ENGINE =~ /opal/
4
+ abort <<-EOS
5
+ Opal Tests
6
+ ==========
7
+
8
+ These tests MUST be run inside opal, not `#{RUBY_ENGINE}' engine
9
+
10
+ To run Array#first tests, for example:
11
+
12
+ opal core_spec/core/array/first_spec.rb
13
+
14
+ EOS
15
+ end
16
+
17
+ require 'opal/spec/autorun'
18
+
19
+ # Spec runner - if in browser, and spec_helper.rb is the main file then
20
+ # just run the spec files immediately.
21
+ if $0 == __FILE__
22
+ Dir['core_spec/**/*.rb'].each { |spec| require spec }
23
+ end
data/lib/opal.rb CHANGED
@@ -5,15 +5,98 @@ require 'opal/context'
5
5
  require 'opal/version'
6
6
 
7
7
  module Opal
8
+ # Base Opal directory - used by build tools
9
+ # @return [String]
8
10
  def self.opal_dir
9
11
  File.expand_path '../..', __FILE__
10
12
  end
11
13
 
14
+ # Returns a string of javascript code for the opal runtime in normal
15
+ # mode.
16
+ # @return [String]
12
17
  def self.runtime_code
13
- File.read File.join(opal_dir, 'opal.js')
18
+ path = File.join opal_dir, 'opal.js'
19
+ return File.read path if File.exists? path
20
+
21
+ build_runtime false
14
22
  end
15
23
 
24
+ # Debug mode code for opal runtime
25
+ # @return [String]
16
26
  def self.runtime_debug_code
17
- File.read File.join(opal_dir, 'opal.debug.js')
27
+ path = File.join opal_dir, 'opal.debug.js'
28
+ return File.read path if File.exists? path
29
+
30
+ build_runtime true
31
+ end
32
+
33
+ # Builds the runtime in normal mode by default.
34
+ #
35
+ # @param [Boolean] debug whether to build in debug mode (or not)
36
+ # @return [String] string of javascript code
37
+ def self.build_runtime(debug = false)
38
+ code = []
39
+ code << HEADER
40
+ code << '(function(undefined) {'
41
+ code << kernel_source(debug)
42
+ code << method_names
43
+ code << corelib_source(debug)
44
+ code << '}).call(this);'
45
+
46
+ code.join "\n"
47
+ end
48
+
49
+ # Returns the source ruby code for the corelib as a string. Corelib is
50
+ # always parsed as one large file.
51
+ # @return [String]
52
+ def self.corelib_source(debug = false)
53
+ order = File.read(File.join(opal_dir, 'core/load_order')).strip.split
54
+ parser = Opal::Parser.new :debug => debug
55
+
56
+ if debug
57
+ order << 'debug'
58
+ order.map do |c|
59
+ parsed = parser.parse File.read(File.join(opal_dir, "core/#{c}.rb")), c
60
+ "opal.FILE = '/core/#{c}.rb';\n#{parsed}"
61
+ end.join("\n")
62
+
63
+ else
64
+ source = order.map { |c| File.read File.join(opal_dir, "core/#{c}.rb") }.join("\n")
65
+ parser.parse source, '(corelib)'
66
+ end
67
+ end
68
+
69
+ # Returns javascript source for the kernel/runtime of opal.
70
+ # @return [String]
71
+ def self.kernel_source(debug = false)
72
+ order = %w[runtime]
73
+ order << 'debug' if debug
74
+ order.map { |c| File.read File.join(opal_dir, "core/#{c}.js") }.join("\n")
18
75
  end
76
+
77
+ # Get all special method names from the parser and generate js code that
78
+ # is passed into runtime. This saves having special names duplicated in
79
+ # runtime AND parser.
80
+ # @return [String]
81
+ def self.method_names
82
+ methods = Opal::Parser::METHOD_NAMES.map { |f, t| "'#{f}': '$#{t}$'" }
83
+ %Q{
84
+ var method_names = {#{ methods.join ', ' }};
85
+ var reverse_method_names = {};
86
+ for (var id in method_names) {
87
+ reverse_method_names[method_names[id]] = id;
88
+ }
89
+ }
90
+ end
91
+
92
+ # Header used in generated runtime code
93
+ HEADER = <<-HEADER
94
+ /*!
95
+ * opal v#{VERSION}
96
+ * http://opalrb.org
97
+ *
98
+ * Copyright 2012, Adam Beynon
99
+ * Released under the MIT license
100
+ */
101
+ HEADER
19
102
  end
data/lib/opal/builder.rb CHANGED
@@ -1,74 +1,157 @@
1
+ #### Opal Builder
2
+ #
3
+ # Builder class is used to build one or more ruby files into a combined
4
+ # output script. The simplest form would be building a single ruby file
5
+ # back into the current working dir:
6
+ #
7
+ # Opal::Builder.new(:files => 'foo.rb')
8
+ #
9
+ # Which would create two files, `foo.js` and `foo.debug.js` to be used
10
+ # in release and debug environments respectively.
11
+ #
12
+ # In real world scenarios, Builder will be used to build entire
13
+ # directories. This is achieved just as easily:
14
+ #
15
+ # Opal::Builder.new(:files => 'my_libs')
16
+ #
17
+ # Where `my_libs` is a directory. This will create a `my_libs.js` and
18
+ # `my_libs.debug.js` file in the current directory.
19
+ #
20
+ # As a special case, when building the `lib` directory, the basename of
21
+ # the current working directory (assumed to be the app/gem name) will be
22
+ # used to construct the output name:
23
+ #
24
+ # # in dir ~/dev/vienna
25
+ # Opal::Builder.new(:files => 'lib')
26
+ #
27
+ # This creates the specially named `vienna.js` and `vienna.debug.js`.
28
+ #
29
+ # As a second special case, building a `spec` or `test` directory will
30
+ # append `test` to the basename of the current directory to name the
31
+ # output files.
32
+ #
33
+ # A custom output destination can be specified using the `:out` option
34
+ # which should point to the output file for the release build mode. The
35
+ # debug output will prefix the extname with `.debug`:
36
+ #
37
+ # Opal::Builder.new(:files => 'lib', :out => 'vienna-0.1.0.js')
38
+ #
39
+ # This will give you `vienna-0.1.0.js` and `vienna-0.1.0.debug.js`.
40
+ #
41
+ # If no input files are specified, then `Builder` will automatically
42
+ # build the `lib/` directory.
43
+ #
44
+ # Opal::Builder.new.build
45
+ #
46
+
47
+ # FileUtils are useful for making sure output directory exists.
1
48
  require 'fileutils'
2
49
 
3
50
  module Opal
51
+ # `Builder.new` takes an optional hash of options to control which
52
+ # files to build and to where. The `options` hash takes these options:
53
+ #
54
+ # * `:files`: specifies an array (or single string) of files/directories
55
+ # to recursively build. _Defaults to `['lib']`_.
56
+ #
57
+ # * `:out`: the file to write the result to. When building a debug build
58
+ # as well, 'debug' will be injected before the extname. Defaults to the
59
+ # first file name.
4
60
  class Builder
5
- def initialize(sources, options = {})
6
- @sources = Array(sources)
61
+ def initialize(options = {})
62
+ @sources = Array(options[:files])
7
63
  @options = options
8
-
9
- @options[:out] = '.' if @options[:out] == '' or !@options[:out]
10
64
  end
11
65
 
12
66
  def build
13
- @parser = Parser.new @options
14
- @factories = {}
67
+ release_out = nil
68
+ debug_out = nil
15
69
 
16
- @sources.each { |s| build_source '.', s }
70
+ raise "No files given" if @sources.empty?
17
71
 
18
- if @options[:join]
19
- File.open(@options[:join], 'w+') do |o|
20
- @factories.each { |path, factory| o.write factory }
72
+ if out = @options[:out]
73
+ release_out = out
74
+ debug_out = out.chomp(File.extname(out)) + '.debug.js'
75
+ else
76
+ if @sources == ['lib']
77
+ out = File.basename(Dir.getwd)
78
+ elsif @sources.include? 'spec'
79
+ out = File.basename(Dir.getwd) + '.test'
80
+ elsif @sources.size == 1
81
+ out = File.basename(@sources[0], '.*')
82
+ else
83
+ out = File.basename(@sources[0], '.*')
21
84
  end
85
+
86
+ release_out = out + '.js'
87
+ debug_out = out + '.debug.js'
22
88
  end
23
- end
24
89
 
25
- def build_source(base, source)
26
- path = base == '.' ? source : File.join(base, source)
90
+ puts "[#{File.basename(Dir.getwd)}] sources: [#{@sources.join ', '}] (#{release_out}, #{debug_out})"
27
91
 
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
92
+ FileUtils.mkdir_p File.dirname(release_out)
33
93
 
34
- elsif File.extname(path) == '.rb'
35
- build_file base, source
36
- end
94
+ files = files_for @sources
95
+
96
+ build_to release_out, files, false
97
+ build_to debug_out, files, true
37
98
  end
38
99
 
39
- def build_file(base, source)
40
- path = base == '.' ? source : File.join(base, source)
41
- code = @parser.parse File.read(path), path
100
+ # Returns an array of all ruby source files to build from the given
101
+ # sources array. The passed sources can be files or directories, where
102
+ # directories will be globbed for all ruby sources.
103
+ # @param [Array<String>] sources array of files/dirs to build
104
+ # @return [Array<String>]
105
+ def files_for(sources)
106
+ files = []
42
107
 
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"
108
+ sources.each do |s|
109
+ if File.directory? s
110
+ files.push *Dir[File.join s, '**/*.rb']
111
+ elsif File.extname(s) == '.rb'
112
+ files << s
113
+ end
47
114
  end
48
115
 
49
- if @options[:join]
50
- @factories[path] = code
51
- elsif @options[:out]
52
- out = output_path base, source
116
+ files
117
+ end
118
+
119
+ def build_to(out, files, debug)
120
+ @parser = Parser.new(:debug => debug)
121
+
122
+ File.open(out, 'w+') do |o|
123
+ # In debug mode, make sure opal runtime is also debug mode
124
+ if debug
125
+ o.puts "if (!opal.debug) {"
126
+ o.puts " throw new Error('This file requires opal.debug.js');"
127
+ o.puts "}"
128
+ end
53
129
 
54
- FileUtils.mkdir_p File.dirname(out)
55
- File.open(out, 'w+') { |o| o.write code }
130
+ files.each { |path| o.write build_file(path) }
56
131
  end
57
132
  end
58
133
 
59
- def output_path(base, source)
60
- fname = source.chomp('.rb') + '.js'
61
- if @options[:out] == '.'
62
- base == '.' ? fname : File.join(base, fname)
134
+ # Build an individual file at the given path, and return a wapped result
135
+ # used to register the factory with the opal runtime. The parser used
136
+ # will be the one set in `#build_to`.
137
+ #
138
+ # @example
139
+ #
140
+ # builder.build_file 'lib/foo.rb'
141
+ # # => "opal.lib('foo', function() { ... });
142
+ #
143
+ # builder.build_file 'spec/foo_spec.rb'
144
+ # # => "opal.file('/spec/foo_spec.rb', function() { ... });
145
+ #
146
+ # @param [String] path relative path to the file to be built
147
+ # @return [String] factory wrapped compiled code
148
+ def build_file(path)
149
+ code = @parser.parse File.read(path), path
150
+
151
+ if /^lib/ =~ path
152
+ "opal.lib('#{path[4..-4]}', function() {\n#{code}\n});\n"
63
153
  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
71
- end
154
+ "opal.file('/#{path}', function() {\n#{code}\n});\n"
72
155
  end
73
156
  end
74
157
  end