opal 0.3.2 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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
+