opal 0.3.2 → 0.3.6

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.
Files changed (203) hide show
  1. data/README.md +85 -127
  2. data/bin/opal +3 -3
  3. data/lib/core.rb +114 -0
  4. data/{gems/core/lib → lib}/core/array.rb +68 -187
  5. data/{gems/core/lib → lib}/core/basic_object.rb +22 -5
  6. data/lib/core/class.rb +38 -0
  7. data/{gems/core/lib → lib}/core/dir.rb +1 -1
  8. data/lib/core/enumerable.rb +33 -0
  9. data/{gems/core/lib → lib}/core/error.rb +1 -4
  10. data/{gems/core/lib → lib}/core/false_class.rb +0 -0
  11. data/{gems/core/lib → lib}/core/file.rb +11 -3
  12. data/{gems/core/lib → lib}/core/hash.rb +12 -0
  13. data/{gems/core/lib → lib}/core/kernel.rb +114 -86
  14. data/lib/core/match_data.rb +33 -0
  15. data/lib/core/module.rb +97 -0
  16. data/{gems/core/lib → lib}/core/nil_class.rb +0 -0
  17. data/{gems/core/lib → lib}/core/numeric.rb +5 -0
  18. data/{gems/core/lib → lib}/core/object.rb +0 -0
  19. data/{gems/core/lib → lib}/core/proc.rb +13 -3
  20. data/{gems/core/lib → lib}/core/range.rb +10 -0
  21. data/{gems/core/lib → lib}/core/regexp.rb +33 -1
  22. data/{gems/core/lib → lib}/core/string.rb +25 -10
  23. data/{gems/core/lib → lib}/core/symbol.rb +3 -3
  24. data/{gems/core/lib → lib}/core/top_self.rb +0 -0
  25. data/{gems/core/lib → lib}/core/true_class.rb +0 -0
  26. data/lib/dev.rb +169 -0
  27. data/{gems/ospec/lib → lib}/ospec.rb +1 -0
  28. data/lib/ospec/autorun.rb +8 -0
  29. data/{gems/ospec/lib → lib}/ospec/dsl.rb +2 -2
  30. data/{gems/ospec/lib → lib}/ospec/example.rb +0 -0
  31. data/{gems/ospec/lib → lib}/ospec/example/before_and_after_hooks.rb +0 -0
  32. data/{gems/ospec/lib → lib}/ospec/example/errors.rb +0 -0
  33. data/{gems/ospec/lib → lib}/ospec/example/example_group.rb +0 -0
  34. data/{gems/ospec/lib → lib}/ospec/example/example_group_factory.rb +0 -3
  35. data/{gems/ospec/lib → lib}/ospec/example/example_group_hierarchy.rb +4 -3
  36. data/{gems/ospec/lib → lib}/ospec/example/example_group_methods.rb +1 -1
  37. data/{gems/ospec/lib → lib}/ospec/example/example_group_proxy.rb +3 -2
  38. data/{gems/ospec/lib → lib}/ospec/example/example_methods.rb +1 -1
  39. data/{gems/ospec/lib → lib}/ospec/example/example_proxy.rb +7 -7
  40. data/{gems/ospec/lib → lib}/ospec/expectations.rb +0 -0
  41. data/{gems/ospec/lib → lib}/ospec/expectations/errors.rb +0 -0
  42. data/{gems/ospec/lib → lib}/ospec/expectations/fail_with.rb +4 -3
  43. data/{gems/ospec/lib → lib}/ospec/expectations/handler.rb +6 -0
  44. data/lib/ospec/helpers/scratch.rb +18 -0
  45. data/{gems/ospec/lib → lib}/ospec/matchers.rb +2 -2
  46. data/{gems/ospec/lib → lib}/ospec/matchers/be.rb +0 -0
  47. data/{gems/ospec/lib → lib}/ospec/matchers/generated_descriptions.rb +0 -0
  48. data/{gems/ospec/lib → lib}/ospec/matchers/operator_matcher.rb +2 -0
  49. data/lib/ospec/matchers/raise_error.rb +38 -0
  50. data/lib/ospec/runner.rb +90 -0
  51. data/{gems/ospec/lib → lib}/ospec/runner/example_group_runner.rb +10 -13
  52. data/lib/ospec/runner/formatter/html_formatter.rb +139 -0
  53. data/{gems/ospec/lib → lib}/ospec/runner/formatter/terminal_formatter.rb +0 -0
  54. data/{gems/ospec/lib → lib}/ospec/runner/options.rb +1 -3
  55. data/{gems/ospec/lib → lib}/ospec/runner/reporter.rb +0 -9
  56. data/lib/racc/parser.rb +165 -0
  57. data/lib/strscan.rb +52 -0
  58. data/{lib → opal_lib}/opal.rb +2 -0
  59. data/opal_lib/opal/build_methods.rb +51 -0
  60. data/opal_lib/opal/builder.rb +164 -0
  61. data/opal_lib/opal/bundle.rb +70 -0
  62. data/opal_lib/opal/command.rb +68 -0
  63. data/{lib → opal_lib}/opal/context.rb +21 -9
  64. data/{lib → opal_lib}/opal/context/console.rb +0 -2
  65. data/opal_lib/opal/context/file_system.rb +34 -0
  66. data/{lib → opal_lib}/opal/context/loader.rb +26 -8
  67. data/opal_lib/opal/gem.rb +84 -0
  68. data/{lib → opal_lib}/opal/rake/builder_task.rb +2 -2
  69. data/opal_lib/opal/rake/spec_task.rb +32 -0
  70. data/{lib → opal_lib}/opal/ruby/nodes.rb +730 -109
  71. data/{lib → opal_lib}/opal/ruby/parser.rb +90 -23
  72. data/opal_lib/opal/ruby/ruby_parser.rb +4862 -0
  73. data/opal_lib/opal/ruby/ruby_parser.y +1454 -0
  74. data/opal_lib/opal/version.rb +4 -0
  75. data/runtime/class.js +359 -0
  76. data/runtime/debug.js +84 -0
  77. data/runtime/fs.js +199 -0
  78. data/runtime/init.js +558 -0
  79. data/runtime/loader.js +351 -0
  80. data/runtime/module.js +109 -0
  81. data/runtime/post.js +10 -0
  82. data/runtime/pre.js +7 -0
  83. data/runtime/runtime.js +351 -0
  84. metadata +88 -175
  85. data/.gitignore +0 -7
  86. data/Changelog +0 -31
  87. data/LICENSE +0 -75
  88. data/Rakefile +0 -86
  89. data/gems/core/README.md +0 -14
  90. data/gems/core/Rakefile +0 -8
  91. data/gems/core/core.gemspec +0 -13
  92. data/gems/core/lib/core.rb +0 -34
  93. data/gems/core/lib/core/class.rb +0 -31
  94. data/gems/core/lib/core/module.rb +0 -100
  95. data/gems/core/lib/core/vm.rb +0 -16
  96. data/gems/core/spec/core/array/append_spec.rb +0 -30
  97. data/gems/core/spec/core/array/assoc_spec.rb +0 -29
  98. data/gems/core/spec/core/array/at_spec.rb +0 -37
  99. data/gems/core/spec/core/array/clear_spec.rb +0 -22
  100. data/gems/core/spec/core/array/collect_bang_spec.rb +0 -27
  101. data/gems/core/spec/core/array/collect_spec.rb +0 -27
  102. data/gems/core/spec/core/array/compact_spec.rb +0 -41
  103. data/gems/core/spec/core/array/concat_spec.rb +0 -15
  104. data/gems/core/spec/core/array/constructor_spec.rb +0 -14
  105. data/gems/core/spec/core/array/each_spec.rb +0 -9
  106. data/gems/core/spec/core/array/element_reference_spec.rb +0 -4
  107. data/gems/core/spec/core/array/first_spec.rb +0 -35
  108. data/gems/core/spec/core/array/include_spec.rb +0 -9
  109. data/gems/core/spec/core/array/join_spec.rb +0 -6
  110. data/gems/core/spec/core/array/last_spec.rb +0 -51
  111. data/gems/core/spec/core/array/length_spec.rb +0 -6
  112. data/gems/core/spec/core/array/map_spec.rb +0 -33
  113. data/gems/core/spec/core/array/reverse_spec.rb +0 -6
  114. data/gems/core/spec/core/builtin_constants/builtin_constants_spec.rb +0 -7
  115. data/gems/core/spec/core/false/and_spec.rb +0 -10
  116. data/gems/core/spec/core/false/inspect_spec.rb +0 -6
  117. data/gems/core/spec/core/false/or_spec.rb +0 -10
  118. data/gems/core/spec/core/false/to_s_spec.rb +0 -6
  119. data/gems/core/spec/core/false/xor_spec.rb +0 -10
  120. data/gems/core/spec/core/file/join_spec.rb +0 -19
  121. data/gems/core/spec/core/hash/assoc_spec.rb +0 -32
  122. data/gems/core/spec/core/kernel/instance_eval_spec.rb +0 -0
  123. data/gems/core/spec/core/kernel/loop_spec.rb +0 -24
  124. data/gems/core/spec/core/kernel/raise_spec.rb +0 -0
  125. data/gems/core/spec/core/module/attr_accessor_spec.rb +0 -28
  126. data/gems/core/spec/core/number/lt_spec.rb +0 -12
  127. data/gems/core/spec/core/string/sub_spec.rb +0 -24
  128. data/gems/core/spec/core/true/and_spec.rb +0 -10
  129. data/gems/core/spec/core/true/inspect_spec.rb +0 -6
  130. data/gems/core/spec/core/true/or_spec.rb +0 -10
  131. data/gems/core/spec/core/true/to_s_spec.rb +0 -6
  132. data/gems/core/spec/core/true/xor_spec.rb +0 -10
  133. data/gems/core/spec/language/and_spec.rb +0 -61
  134. data/gems/core/spec/language/array_spec.rb +0 -68
  135. data/gems/core/spec/language/block_spec.rb +0 -38
  136. data/gems/core/spec/language/break_spec.rb +0 -36
  137. data/gems/core/spec/language/case_spec.rb +0 -103
  138. data/gems/core/spec/language/def_spec.rb +0 -21
  139. data/gems/core/spec/language/eigenclass_spec.rb +0 -60
  140. data/gems/core/spec/language/file_spec.rb +0 -13
  141. data/gems/core/spec/language/fixtures/block.rb +0 -21
  142. data/gems/core/spec/language/fixtures/super.rb +0 -293
  143. data/gems/core/spec/language/hash_spec.rb +0 -29
  144. data/gems/core/spec/language/if_spec.rb +0 -54
  145. data/gems/core/spec/language/loop_spec.rb +0 -11
  146. data/gems/core/spec/language/metaclass_spec.rb +0 -21
  147. data/gems/core/spec/language/method_spec.rb +0 -124
  148. data/gems/core/spec/language/next_spec.rb +0 -25
  149. data/gems/core/spec/language/or_spec.rb +0 -34
  150. data/gems/core/spec/language/redo_spec.rb +0 -24
  151. data/gems/core/spec/language/regexp_spec.rb +0 -26
  152. data/gems/core/spec/language/rescue_spec.rb +0 -20
  153. data/gems/core/spec/language/return_spec.rb +0 -47
  154. data/gems/core/spec/language/string_spec.rb +0 -25
  155. data/gems/core/spec/language/super_spec.rb +0 -32
  156. data/gems/core/spec/language/until_spec.rb +0 -157
  157. data/gems/core/spec/language/variables_spec.rb +0 -155
  158. data/gems/core/spec/language/while_spec.rb +0 -163
  159. data/gems/core/spec/spec_helper.rb +0 -5
  160. data/gems/core_fs/README.md +0 -19
  161. data/gems/dev/Rakefile +0 -5
  162. data/gems/dev/lib/dev.js +0 -99
  163. data/gems/dev/lib/dev/generator.js +0 -1264
  164. data/gems/dev/lib/dev/parser.js +0 -979
  165. data/gems/dev/lib/dev/ruby_parser.js +0 -1088
  166. data/gems/dev/lib/dev/ruby_parser.y +0 -1267
  167. data/gems/dev/lib/dev/string_scanner.js +0 -38
  168. data/gems/dev/tools/racc2js/README.md +0 -39
  169. data/gems/dev/tools/racc2js/math_parser.js +0 -222
  170. data/gems/dev/tools/racc2js/math_parser.rb +0 -133
  171. data/gems/dev/tools/racc2js/math_parser.y +0 -28
  172. data/gems/dev/tools/racc2js/parser.js +0 -218
  173. data/gems/dev/tools/racc2js/racc2js.rb +0 -153
  174. data/gems/json/README.md +0 -4
  175. data/gems/json/json.gemspec +0 -14
  176. data/gems/json/lib/json.rb +0 -64
  177. data/gems/json/lib/json/ext.rb +0 -51
  178. data/gems/json/lib/json/json2.js +0 -481
  179. data/gems/ospec/README.md +0 -0
  180. data/gems/ospec/lib/ospec/autorun.rb +0 -3
  181. data/gems/ospec/lib/ospec/runner.rb +0 -40
  182. data/gems/ospec/lib/ospec/runner/formatter/html_formatter.rb +0 -91
  183. data/gems/ospec/ospec.gemspec +0 -0
  184. data/gems/rquery/README.md +0 -9
  185. data/gems/rquery/lib/rquery.rb +0 -10
  186. data/gems/rquery/lib/rquery/ajax.rb +0 -4
  187. data/gems/rquery/lib/rquery/css.rb +0 -96
  188. data/gems/rquery/lib/rquery/document.rb +0 -25
  189. data/gems/rquery/lib/rquery/element.rb +0 -292
  190. data/gems/rquery/lib/rquery/event.rb +0 -108
  191. data/gems/rquery/lib/rquery/jquery.js +0 -8177
  192. data/gems/rquery/lib/rquery/request.rb +0 -138
  193. data/gems/rquery/lib/rquery/response.rb +0 -49
  194. data/gems/rquery/rquery.gemspec +0 -16
  195. data/lib/opal.js +0 -1597
  196. data/lib/opal/builder.rb +0 -117
  197. data/lib/opal/bundle.rb +0 -131
  198. data/lib/opal/command.rb +0 -11
  199. data/lib/opal/context/file_system.rb +0 -19
  200. data/lib/opal/gem.rb +0 -153
  201. data/lib/opal/ruby/ruby_parser.rb +0 -5170
  202. data/lib/opal/ruby/ruby_parser.y +0 -1298
  203. data/opal.gemspec +0 -15
@@ -16,10 +16,8 @@ module Spec
16
16
  end
17
17
 
18
18
  def formatters
19
- # puts "formatters: #{@formatters.inspect}"
20
19
  return @formatters if @formatters
21
- # puts "still down here.."
22
- if RUBY_PLATFORM == "browser"
20
+ if RUBY_ENGINE == "opal-browser"
23
21
  @formatters ||= [Spec::Runner::Formatter::HtmlFormatter.new(self)]
24
22
  else
25
23
  @formatters ||= [Spec::Runner::Formatter::TerminalFormatter.new(self)]
@@ -14,10 +14,7 @@ module Spec
14
14
 
15
15
  def start(number_of_examples)
16
16
  @start_time = 0
17
- puts "formatters isss:"
18
- # `console.log(#{formatters})`
19
17
  formatters.each do |f|
20
- # puts "in hereeee"
21
18
  f.start number_of_examples
22
19
  end
23
20
  end
@@ -40,17 +37,11 @@ module Spec
40
37
  end
41
38
 
42
39
  def example_finished(example, error)
43
- puts "== example finished"
44
40
  if error.nil?
45
- puts "no error"
46
41
  example_passed example
47
42
  elsif Spec::Example::ExamplePendingError === error
48
- puts "pengin error"
49
43
  example_pending example, error.message
50
44
  else
51
- puts "failed"
52
- `console.log(error)`
53
- `console.log(error.message)`
54
45
  example_failed example, error
55
46
  end
56
47
  end
@@ -0,0 +1,165 @@
1
+ # Opal port of racc/parser.rb.
2
+ #
3
+ # This is the runtime for racc generated parsers inside opal. It is a port
4
+ # of racc/parser.rb from ruby stdlib but with optimizations to make it run
5
+ # faster on opal, which is ecspecially important in the browser. This
6
+ # implementation also has a pure js routine for extra speeds gains which is
7
+ # used in preference to the ruby implementation.
8
+ #
9
+ # Original license:
10
+ #
11
+ # $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
12
+ #
13
+ # Copyright (c) 1999-2006 Minero Aoki
14
+ #
15
+ # This program is free software.
16
+ # You can distribute/modify this program under the same terms of ruby.
17
+ #
18
+ # As a special exception, when this code is copied by Racc
19
+ # into a Racc output file, you may use that output file
20
+ # without restriction.
21
+ module Racc
22
+
23
+ class Parser
24
+
25
+ def _racc_setup
26
+ Racc_arg
27
+ end
28
+
29
+ def do_parse
30
+ _racc_do_parse_rb _racc_setup, false
31
+ end
32
+
33
+ def _racc_do_parse_rb(arg, in_debug)
34
+ action_table = arg[0]
35
+ action_check = arg[1]
36
+ action_default = arg[2]
37
+ action_pointer = arg[3]
38
+
39
+ goto_table = arg[4]
40
+ goto_check = arg[5]
41
+ goto_default = arg[6]
42
+ goto_pointer = arg[7]
43
+
44
+ nt_base = arg[8]
45
+ reduce_table = arg[9]
46
+ token_table = arg[10]
47
+ shift_n = arg[11]
48
+ reduce_n = arg[12]
49
+
50
+ use_result = arg[13]
51
+
52
+ # racc sys vars
53
+ racc_state = [0]
54
+ racc_tstack = []
55
+ racc_vstack = []
56
+
57
+ racc_t = nil
58
+ racc_tok = nil
59
+ racc_val = nil
60
+ racc_read_next = true
61
+
62
+ racc_user_yyerror = false
63
+ racc_error_status = 0
64
+
65
+ token = nil; act = nil; i = nil; nerr = nil; custate = nil
66
+
67
+ while true
68
+ i = action_pointer[racc_state[-1]]
69
+
70
+ if i
71
+ if racc_read_next
72
+ if racc_t != 0 # not EOF
73
+ token = next_token
74
+
75
+ racc_tok = token[0]
76
+ racc_val = token[1]
77
+
78
+ if racc_tok == false # EOF
79
+ racc_t = 0
80
+ else
81
+ racc_t = token_table[racc_tok]
82
+ racc_t = 1 unless racc_t
83
+ # racc_t ||= 1
84
+ end
85
+
86
+ racc_read_next = false
87
+ end
88
+ end
89
+
90
+ i += racc_t
91
+
92
+ if (i < 0) || (act = action_table[i]).nil? || (action_check[i] != racc_state[-1])
93
+ act = action_default[racc_state[-1]]
94
+ end
95
+
96
+ else
97
+ act = action_default[racc_state[-1]]
98
+ end
99
+
100
+ if act > 0 && act < shift_n
101
+ if racc_error_status > 0
102
+ if racc_t != 1
103
+ racc_error_status -= 1
104
+ end
105
+ end
106
+
107
+ racc_vstack.push racc_val
108
+ curstate = act
109
+ racc_state << act
110
+ racc_read_next = true
111
+
112
+ elsif act < 0 && act > -reduce_n
113
+ reduce_i = act * -3
114
+ reduce_len = reduce_table[reduce_i]
115
+ reduce_to = reduce_table[reduce_i + 1]
116
+ method_id = reduce_table[reduce_i + 2]
117
+
118
+ tmp_v = racc_vstack.last reduce_len
119
+
120
+ racc_state.pop reduce_len
121
+ racc_vstack.pop reduce_len
122
+ racc_tstack.pop reduce_len
123
+
124
+ if use_result
125
+ reduce_call_result = self.__send__ method_id, tmp_v, nil, tmp_v[0]
126
+ racc_vstack.push reduce_call_result
127
+ else
128
+ raise "not using result??"
129
+ end
130
+
131
+ racc_tstack.push reduce_to
132
+
133
+ k1 = reduce_to - nt_base
134
+
135
+ if (reduce_i = goto_pointer[k1]) != nil
136
+ reduce_i += racc_state[-1]
137
+
138
+ if (reduce_i >= 0) && ((curstate = goto_table[reduce_i]) != nil) && (goto_check[reduce_i] == k1)
139
+ racc_state.push curstate
140
+ else
141
+ racc_state.push goto_default[k1]
142
+ end
143
+
144
+ else
145
+ racc_state.push goto_default[k1]
146
+ end
147
+
148
+ elsif act == shift_n
149
+ # action
150
+ return racc_vstack[0]
151
+
152
+ elsif act == -reduce_n
153
+ # reduce
154
+ raise "Opal Syntax Error: unexpected '#{racc_tok.inspect}'"
155
+
156
+ else
157
+ raise "Rac: unknown action: #{act}"
158
+ end
159
+
160
+ # raise "and finished loop"
161
+ end
162
+ end # _racc_do_parse_rb
163
+ end
164
+ end
165
+
data/lib/strscan.rb ADDED
@@ -0,0 +1,52 @@
1
+ class StringScanner
2
+
3
+ def initialize(str)
4
+ `self._str = str;
5
+ self._at = 0;
6
+ self._matched = "";
7
+ self._working_string = str;`
8
+ nil
9
+ end
10
+
11
+ def scan(reg)
12
+ `reg = new RegExp('^' + reg.toString().substr(1, reg.toString().length - 2));
13
+ var res = reg.exec(self._working_string);
14
+
15
+ if (res == null) {
16
+ self.matched = "";
17
+ return Qfalse;
18
+ }
19
+ else if (typeof res == 'object') {
20
+ self._at += res[0].length;
21
+ self._working_string = self._working_string.substr(res[0].length);
22
+ self._matched = res[0];
23
+ return res[0];
24
+ }
25
+ else if (typeof res == 'string') {
26
+ self._at += res.length;
27
+ self._working_string = self._working_string.substr(res.length);
28
+ return res;
29
+ }
30
+ else {
31
+ return Qfalse;
32
+ }`
33
+ end
34
+
35
+ def check(reg)
36
+ `reg = new RegExp('^' + reg.toString().substr(1, reg.toString().length - 2));
37
+ return reg.exec(self._working_string) ? Qtrue : Qfalse;`
38
+ end
39
+
40
+ def peek(len)
41
+ `return self._working_string.substr(0, len);`
42
+ end
43
+
44
+ def eos?
45
+ `return self._working_string.length == 0 ? Qtrue : Qfalse;`
46
+ end
47
+
48
+ def matched
49
+ `return self._matched;`
50
+ end
51
+ end
52
+
@@ -1,9 +1,11 @@
1
1
  require 'rubygems'
2
+ require 'thor'
2
3
 
3
4
  module Opal
4
5
 
5
6
  end
6
7
 
8
+ require 'opal/version'
7
9
  require 'opal/ruby/parser'
8
10
 
9
11
  require 'opal/gem'
@@ -0,0 +1,51 @@
1
+ module Opal
2
+
3
+ module BuildMethods
4
+
5
+ # Returns the result of the compiled file ready for opal to load.
6
+ #
7
+ # `relative_path` is used for the name the built file should have.
8
+ # This is used for building a singular rb or js file into the
9
+ # compiled output, and will avoid the user's dir setup being exposed
10
+ # in production code. It will be of the form
11
+ # `lib/some_lib/some_lib.rb`
12
+ #
13
+ # @param [String] full_path The full pathname to the file to build
14
+ # @paeam [String] relative_path The pathname to be used in the build
15
+ # file.
16
+ #
17
+ # @return [String]
18
+ def wrap_source(full_path, relative_path = nil)
19
+ relative_path ||= full_path
20
+ ext = File.extname full_path
21
+ # relative_path = relative_path.sub(/\.rb/, '.js') if ext == '.rb'
22
+ content = compile_source full_path
23
+
24
+ "opal.register('#{relative_path}', #{content});\n"
25
+ end
26
+
27
+ # Simply compile the given source code at the given path. This is
28
+ # for compiling ruby or javascript sources only. This can be used
29
+ # for any method that builds for the browser.
30
+ #
31
+ # @param [String] full_path location of the source to build
32
+ # @return [String] compiled source
33
+ def compile_source(full_path)
34
+ ext = File.extname full_path
35
+ src = File.read full_path
36
+
37
+ case ext
38
+ when '.js'
39
+ "function($rb, self, __FILE__) { #{src} }"
40
+
41
+ when '.rb'
42
+ src = Opal::RubyParser.new(src).parse!.generate_top
43
+ "function($rb, self, __FILE__) { #{src} }"
44
+
45
+ else
46
+ raise "Bad file type for wrapping. Must be ruby or javascript"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,164 @@
1
+ require 'fileutils'
2
+ require 'opal/build_methods'
3
+
4
+ module Opal
5
+ # Builder is used for compiling simple ruby files into javascript files
6
+ # through the command line or a rake task. It is used for non bundle based
7
+ # building systems, and is meant for building small scale pages rather than
8
+ # applications.
9
+ class Builder
10
+ include BuildMethods
11
+
12
+ OPAL_PATH = File.expand_path(File.join('..', '..', '..'), __FILE__)
13
+
14
+ STDLIB_PATH = File.join OPAL_PATH, 'lib'
15
+
16
+ RUNTIME_PATH = File.join OPAL_PATH, 'runtime'
17
+
18
+ def build_runtime
19
+ code = ''
20
+
21
+ %w[pre runtime init class module fs loader debug post].each do |f|
22
+ code += File.read(File.join RUNTIME_PATH, f + '.js')
23
+ end
24
+
25
+ code
26
+ end
27
+
28
+ # Builds core opal runtime + core libs, and returns as a string.
29
+ # This can then just be used directly by any compiled code. The
30
+ # core lib is then auto loaded so it is ready for running.
31
+ def build_core
32
+ code = build_runtime
33
+ code += build_stdlib('core.rb', 'core/*.rb')
34
+ code += "opal.require('core');"
35
+
36
+ code
37
+ end
38
+
39
+ # Builds the opal parser and dev.rb file, and returns as a string.
40
+ def build_parser
41
+ code = ''
42
+
43
+ %w[opal/ruby/nodes opal/ruby/parser opal/ruby/ruby_parser].each do |src|
44
+ full = File.join OPAL_PATH, 'opal_lib', src + '.rb'
45
+ compiled = compile_source full
46
+ code += "opal.register('#{src}.rb', #{compiled});"
47
+ end
48
+
49
+ code += build_stdlib 'racc/parser.rb', 'strscan.rb', 'dev.rb'
50
+ code += "opal.require('dev');"
51
+
52
+ code
53
+ end
54
+
55
+ # Build the given sources from the standard library. These can be
56
+ # globs. Returns a string of all content.
57
+ def build_stdlib(*files)
58
+ code = []
59
+ Dir.chdir(STDLIB_PATH) do
60
+ Dir.[](*files).each do |lib|
61
+ full_path = File.join STDLIB_PATH, lib
62
+ code << wrap_source(full_path, lib)
63
+ end
64
+ end
65
+
66
+ code.join ''
67
+ end
68
+
69
+ # Takes a hash of build options.
70
+ #
71
+ # :project_dir - The base directory to work in. If not given then cwd is used.
72
+ #
73
+ # :files - May be a single source, a directory, or an array of ruby/js src
74
+ #
75
+ # :out - The output file. All sources are built into a single output file.
76
+ # If this is not given, it will default to project_dir/javascripts/name.js
77
+ # where name is the basename of the given project_dir or cwd.
78
+ #
79
+ # :main - only useful when more than one input is given to determine which
80
+ # file is automatically loaded on running in the browser.
81
+ #
82
+ # :watch - watch all sources and automatically recompile if one changes
83
+ #
84
+ # :pre - pre content to add. Could be copyright, or extra code etc
85
+ #
86
+ # :post - post content.. could be extra code etc
87
+ #
88
+ # Also, if no output is given, then one file will be used for all sources,
89
+ # and the files name will be taken as the basename of the root_dir/cwd.
90
+ #
91
+ # @param {Hash} options Build options to use
92
+ def build(options = {})
93
+ files = options[:files] || []
94
+ files = [files] unless files.is_a? Array
95
+ options[:files] = files = Dir.[](*files)
96
+
97
+ raise "Opal::Builder - No input files could be found" if files.empty?
98
+
99
+ main = options[:main]
100
+
101
+ if main == true
102
+ options[:main] = files.first
103
+ elsif main
104
+ raise "Opal::Builder - Main file does not exist!" unless File.exists? main
105
+ files << main unless files.include? main
106
+ elsif main == false
107
+ options[:main] = false
108
+ else
109
+ options[:main] = files.first
110
+ end
111
+
112
+ main = options[:main]
113
+
114
+ unless options[:out]
115
+ options[:out] = main.sub /\.rb$/, '.js'
116
+ end
117
+
118
+ FileUtils.mkdir_p File.dirname(options[:out])
119
+
120
+ rebuild options
121
+ if options[:watch]
122
+ puts "Watching for changes.."
123
+ loop do
124
+ out_mtime = File.stat(options[:out]).mtime
125
+ options[:files].each do |file|
126
+ if File.stat(file).mtime > out_mtime
127
+ puts "#{Time.now} rebuilding - changes detected in #{file}"
128
+ rebuild options
129
+ end
130
+ end
131
+
132
+ begin
133
+ sleep 1
134
+ rescue Interrupt
135
+ exit 0
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ private
142
+
143
+ # Does the actual rebuild of a project
144
+ def rebuild(options)
145
+ puts "rebuilding to #{options[:out]}"
146
+ puts options[:files].inspect
147
+ File.open(options[:out], 'w') do |out|
148
+ # out.write @pre if @pre
149
+
150
+ options[:files].each do |file|
151
+ out.write wrap_source file
152
+ end
153
+
154
+ if options[:main]
155
+ main = options[:main].sub(/\.rb$/, '')
156
+ out.write "opal.require('#{main}');\n"
157
+ end
158
+
159
+ # out.write @post if @post
160
+ end
161
+ end
162
+ end
163
+ end
164
+