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.
Files changed (282) hide show
  1. data/.gitignore +13 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE +20 -0
  4. data/README.md +11 -116
  5. data/Rakefile +126 -0
  6. data/bin/opal +1 -2
  7. data/docs/spec_runner.html +16 -0
  8. data/index.html +434 -0
  9. data/lib/opal.rb +14 -15
  10. data/lib/opal/builder.rb +46 -148
  11. data/lib/opal/command.rb +45 -115
  12. data/lib/opal/context.rb +139 -78
  13. data/lib/opal/dependency_builder.rb +34 -0
  14. data/lib/opal/environment.rb +92 -0
  15. data/lib/opal/parser/grammar.rb +4915 -0
  16. data/lib/opal/{parser.y → parser/grammar.y} +430 -284
  17. data/lib/opal/parser/lexer.rb +1329 -0
  18. data/lib/opal/parser/parser.rb +1460 -0
  19. data/lib/opal/parser/scope.rb +140 -0
  20. data/lib/opal/parser/sexp.rb +17 -0
  21. data/lib/opal/version.rb +2 -1
  22. data/opal.gemspec +23 -0
  23. data/opal.js +3149 -4162
  24. data/runtime/README.md +25 -0
  25. data/runtime/corelib/alpha.rb +10 -0
  26. data/runtime/corelib/array.rb +962 -0
  27. data/runtime/corelib/basic_object.rb +66 -0
  28. data/runtime/corelib/boolean.rb +44 -0
  29. data/runtime/corelib/class.rb +43 -0
  30. data/runtime/corelib/comparable.rb +25 -0
  31. data/runtime/corelib/complex.rb +2 -0
  32. data/runtime/corelib/dir.rb +29 -0
  33. data/runtime/corelib/enumerable.rb +316 -0
  34. data/runtime/corelib/enumerator.rb +80 -0
  35. data/runtime/corelib/error.rb +25 -0
  36. data/runtime/corelib/file.rb +80 -0
  37. data/runtime/corelib/hash.rb +503 -0
  38. data/runtime/corelib/io.rb +44 -0
  39. data/runtime/corelib/kernel.rb +237 -0
  40. data/runtime/corelib/load_order +29 -0
  41. data/runtime/corelib/match_data.rb +37 -0
  42. data/runtime/corelib/module.rb +171 -0
  43. data/runtime/corelib/native.rb +50 -0
  44. data/runtime/corelib/nil_class.rb +47 -0
  45. data/runtime/corelib/numeric.rb +219 -0
  46. data/runtime/corelib/object.rb +21 -0
  47. data/runtime/corelib/proc.rb +42 -0
  48. data/runtime/corelib/range.rb +38 -0
  49. data/runtime/corelib/rational.rb +16 -0
  50. data/runtime/corelib/regexp.rb +63 -0
  51. data/runtime/corelib/string.rb +185 -0
  52. data/runtime/corelib/struct.rb +97 -0
  53. data/runtime/corelib/time.rb +196 -0
  54. data/runtime/corelib/top_self.rb +7 -0
  55. data/runtime/gemlib/alpha.rb +5 -0
  56. data/runtime/gemlib/kernel.rb +17 -0
  57. data/runtime/gemlib/load_order +2 -0
  58. data/runtime/kernel/class.js +256 -0
  59. data/runtime/kernel/debug.js +42 -0
  60. data/runtime/kernel/init.js +114 -0
  61. data/runtime/kernel/load_order +5 -0
  62. data/runtime/kernel/loader.js +151 -0
  63. data/runtime/kernel/runtime.js +414 -0
  64. data/runtime/spec/README.md +34 -0
  65. data/runtime/spec/core/array/allocate_spec.rb +15 -0
  66. data/runtime/spec/core/array/append_spec.rb +31 -0
  67. data/runtime/spec/core/array/assoc_spec.rb +29 -0
  68. data/runtime/spec/core/array/at_spec.rb +38 -0
  69. data/runtime/spec/core/array/clear_spec.rb +22 -0
  70. data/runtime/spec/core/array/collect_spec.rb +3 -0
  71. data/runtime/spec/core/array/compact_spec.rb +42 -0
  72. data/runtime/spec/core/array/concat_spec.rb +21 -0
  73. data/runtime/spec/core/array/constructor_spec.rb +24 -0
  74. data/runtime/spec/core/array/count_spec.rb +11 -0
  75. data/runtime/spec/core/array/delete_at_spec.rb +31 -0
  76. data/runtime/spec/core/array/delete_if_spec.rb +24 -0
  77. data/runtime/spec/core/array/delete_spec.rb +26 -0
  78. data/runtime/spec/core/array/each_index_spec.rb +33 -0
  79. data/runtime/spec/core/array/each_spec.rb +11 -0
  80. data/runtime/spec/core/array/element_reference_spec.rb +136 -0
  81. data/runtime/spec/core/array/element_set_spec.rb +7 -0
  82. data/runtime/spec/core/array/empty_spec.rb +10 -0
  83. data/runtime/spec/core/array/eql_spec.rb +3 -0
  84. data/runtime/spec/core/array/equal_value_spec.rb +3 -0
  85. data/runtime/spec/core/array/fetch_spec.rb +26 -0
  86. data/runtime/spec/core/array/first_spec.rb +54 -0
  87. data/runtime/spec/core/array/fixtures/classes.rb +8 -0
  88. data/runtime/spec/core/array/flatten_spec.rb +41 -0
  89. data/runtime/spec/core/array/include_spec.rb +20 -0
  90. data/runtime/spec/core/array/insert_spec.rb +59 -0
  91. data/runtime/spec/core/array/last_spec.rb +57 -0
  92. data/runtime/spec/core/array/length_spec.rb +3 -0
  93. data/runtime/spec/core/array/map_spec.rb +3 -0
  94. data/runtime/spec/core/array/plus_spec.rb +16 -0
  95. data/runtime/spec/core/array/pop_spec.rb +79 -0
  96. data/runtime/spec/core/array/push_spec.rb +19 -0
  97. data/runtime/spec/core/array/rassoc_spec.rb +12 -0
  98. data/runtime/spec/core/array/reject_spec.rb +54 -0
  99. data/runtime/spec/core/array/replace_spec.rb +3 -0
  100. data/runtime/spec/core/array/reverse_each_spec.rb +18 -0
  101. data/runtime/spec/core/array/reverse_spec.rb +9 -0
  102. data/runtime/spec/core/array/shared/collect.rb +53 -0
  103. data/runtime/spec/core/array/shared/eql.rb +19 -0
  104. data/runtime/spec/core/array/shared/length.rb +6 -0
  105. data/runtime/spec/core/array/shared/replace.rb +31 -0
  106. data/runtime/spec/core/class/new_spec.rb +19 -0
  107. data/runtime/spec/core/enumerable/all_spec.rb +102 -0
  108. data/runtime/spec/core/enumerable/any_spec.rb +115 -0
  109. data/runtime/spec/core/enumerable/collect_spec.rb +3 -0
  110. data/runtime/spec/core/enumerable/count_spec.rb +29 -0
  111. data/runtime/spec/core/enumerable/detect_spec.rb +3 -0
  112. data/runtime/spec/core/enumerable/find_spec.rb +3 -0
  113. data/runtime/spec/core/enumerable/fixtures/classes.rb +26 -0
  114. data/runtime/spec/core/enumerable/shared/collect.rb +12 -0
  115. data/runtime/spec/core/enumerable/shared/entries.rb +7 -0
  116. data/runtime/spec/core/enumerable/shared/find.rb +49 -0
  117. data/runtime/spec/core/enumerable/to_a_spec.rb +7 -0
  118. data/runtime/spec/core/false/and_spec.rb +11 -0
  119. data/runtime/spec/core/false/inspect_spec.rb +7 -0
  120. data/runtime/spec/core/false/or_spec.rb +11 -0
  121. data/runtime/spec/core/false/to_s_spec.rb +7 -0
  122. data/runtime/spec/core/false/xor_spec.rb +11 -0
  123. data/runtime/spec/core/hash/allocate_spec.rb +15 -0
  124. data/runtime/spec/core/hash/assoc_spec.rb +29 -0
  125. data/runtime/spec/core/hash/clear_spec.rb +21 -0
  126. data/runtime/spec/core/hash/clone_spec.rb +12 -0
  127. data/runtime/spec/core/hash/default_spec.rb +6 -0
  128. data/runtime/spec/core/hash/delete_if_spec.rb +15 -0
  129. data/runtime/spec/core/hash/element_reference_spec.rb +16 -0
  130. data/runtime/spec/core/hash/element_set_spec.rb +8 -0
  131. data/runtime/spec/core/hash/new_spec.rb +13 -0
  132. data/runtime/spec/core/matchdata/to_a_spec.rb +7 -0
  133. data/runtime/spec/core/nil/and_spec.rb +12 -0
  134. data/runtime/spec/core/nil/inspect_spec.rb +8 -0
  135. data/runtime/spec/core/nil/nil_spec.rb +8 -0
  136. data/runtime/spec/core/nil/or_spec.rb +12 -0
  137. data/runtime/spec/core/nil/to_a_spec.rb +8 -0
  138. data/runtime/spec/core/nil/to_f_spec.rb +12 -0
  139. data/runtime/spec/core/nil/to_i_spec.rb +12 -0
  140. data/runtime/spec/core/nil/to_s_spec.rb +8 -0
  141. data/runtime/spec/core/nil/xor_spec.rb +12 -0
  142. data/runtime/spec/core/numeric/equal_value_spec.rb +11 -0
  143. data/runtime/spec/core/object/is_a_spec.rb +2 -0
  144. data/runtime/spec/core/object/shared/kind_of.rb +0 -0
  145. data/runtime/spec/core/regexp/match_spec.rb +23 -0
  146. data/runtime/spec/core/regexp/shared/match.rb +11 -0
  147. data/runtime/spec/core/symbol/to_proc_spec.rb +8 -0
  148. data/runtime/spec/core/true/and_spec.rb +11 -0
  149. data/runtime/spec/core/true/inspect_spec.rb +7 -0
  150. data/runtime/spec/core/true/or_spec.rb +11 -0
  151. data/runtime/spec/core/true/to_s_spec.rb +7 -0
  152. data/runtime/spec/core/true/xor_spec.rb +11 -0
  153. data/runtime/spec/language/alias_spec.rb +25 -0
  154. data/runtime/spec/language/and_spec.rb +62 -0
  155. data/runtime/spec/language/array_spec.rb +68 -0
  156. data/runtime/spec/language/block_spec.rb +105 -0
  157. data/runtime/spec/language/break_spec.rb +49 -0
  158. data/runtime/spec/language/case_spec.rb +165 -0
  159. data/runtime/spec/language/defined_spec.rb +80 -0
  160. data/runtime/spec/language/ensure_spec.rb +82 -0
  161. data/runtime/spec/language/fixtures/block.rb +19 -0
  162. data/runtime/spec/language/fixtures/break.rb +39 -0
  163. data/runtime/spec/language/fixtures/defined.rb +9 -0
  164. data/runtime/spec/language/fixtures/ensure.rb +37 -0
  165. data/runtime/spec/language/fixtures/next.rb +46 -0
  166. data/runtime/spec/language/fixtures/send.rb +36 -0
  167. data/runtime/spec/language/fixtures/super.rb +43 -0
  168. data/runtime/spec/language/hash_spec.rb +43 -0
  169. data/runtime/spec/language/if_spec.rb +278 -0
  170. data/runtime/spec/language/loop_spec.rb +32 -0
  171. data/runtime/spec/language/next_spec.rb +128 -0
  172. data/runtime/spec/language/or_spec.rb +65 -0
  173. data/runtime/spec/language/predefined_spec.rb +21 -0
  174. data/runtime/spec/language/regexp/interpolation_spec.rb +9 -0
  175. data/runtime/spec/language/regexp_spec.rb +7 -0
  176. data/runtime/spec/language/send_spec.rb +105 -0
  177. data/runtime/spec/language/string_spec.rb +4 -0
  178. data/runtime/spec/language/super_spec.rb +18 -0
  179. data/runtime/spec/language/symbol_spec.rb +41 -0
  180. data/runtime/spec/language/undef_spec.rb +16 -0
  181. data/runtime/spec/language/unless_spec.rb +44 -0
  182. data/runtime/spec/language/until_spec.rb +137 -0
  183. data/runtime/spec/language/variables_spec.rb +28 -0
  184. data/runtime/spec/language/versions/hash_1.9.rb +20 -0
  185. data/runtime/spec/language/while_spec.rb +175 -0
  186. data/runtime/spec/library/stringscanner/scan_spec.rb +36 -0
  187. data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +49 -0
  188. data/runtime/spec/opal/opal/defined_spec.rb +15 -0
  189. data/runtime/spec/opal/opal/function_spec.rb +11 -0
  190. data/runtime/spec/opal/opal/native_spec.rb +16 -0
  191. data/runtime/spec/opal/opal/null_spec.rb +10 -0
  192. data/runtime/spec/opal/opal/number_spec.rb +11 -0
  193. data/runtime/spec/opal/opal/object_spec.rb +16 -0
  194. data/runtime/spec/opal/opal/string_spec.rb +11 -0
  195. data/runtime/spec/opal/opal/typeof_spec.rb +9 -0
  196. data/runtime/spec/opal/opal/undefined_spec.rb +10 -0
  197. data/runtime/spec/opal/true/case_compare_spec.rb +12 -0
  198. data/runtime/spec/opal/true/class_spec.rb +10 -0
  199. data/runtime/spec/spec_helper.rb +25 -0
  200. data/runtime/stdlib/base64.rb +91 -0
  201. data/runtime/stdlib/date.rb +4 -0
  202. data/{stdlib → runtime/stdlib}/dev.rb +0 -0
  203. data/runtime/stdlib/forwardable.rb +33 -0
  204. data/runtime/stdlib/optparse.rb +0 -0
  205. data/runtime/stdlib/pp.rb +6 -0
  206. data/{stdlib → runtime/stdlib}/racc/parser.rb +0 -0
  207. data/runtime/stdlib/rbconfig.rb +0 -0
  208. data/runtime/stdlib/si.rb +17 -0
  209. data/runtime/stdlib/strscan.rb +53 -0
  210. data/runtime/stdlib/uri.rb +111 -0
  211. data/runtime/stdlib/uri/common.rb +1014 -0
  212. data/runtime/stdlib/uri/ftp.rb +261 -0
  213. data/runtime/stdlib/uri/generic.rb +1599 -0
  214. data/runtime/stdlib/uri/http.rb +106 -0
  215. data/runtime/stdlib/uri/https.rb +22 -0
  216. data/runtime/stdlib/uri/ldap.rb +260 -0
  217. data/runtime/stdlib/uri/ldaps.rb +20 -0
  218. data/runtime/stdlib/uri/mailto.rb +280 -0
  219. data/spec/builder/build_source_spec.rb +52 -0
  220. data/spec/builder/fixtures/build_source/adam.rb +0 -0
  221. data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
  222. data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
  223. data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
  224. data/spec/builder/fixtures/build_source/beynon.rb +0 -0
  225. data/spec/builder/fixtures/build_source/charles.js +0 -0
  226. data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
  227. data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
  228. data/spec/builder/fixtures/build_source/foo/x.js +0 -0
  229. data/spec/builder/fixtures/build_source/foo/y.js +0 -0
  230. data/spec/builder/output_path_spec.rb +50 -0
  231. data/spec/grammar/alias_spec.rb +26 -0
  232. data/spec/grammar/and_spec.rb +13 -0
  233. data/spec/grammar/array_spec.rb +22 -0
  234. data/spec/grammar/attrasgn_spec.rb +28 -0
  235. data/spec/grammar/begin_spec.rb +38 -0
  236. data/spec/grammar/block_spec.rb +12 -0
  237. data/spec/grammar/break_spec.rb +17 -0
  238. data/spec/grammar/call_spec.rb +58 -0
  239. data/spec/grammar/class_spec.rb +35 -0
  240. data/spec/grammar/const_spec.rb +13 -0
  241. data/spec/grammar/cvar_spec.rb +11 -0
  242. data/spec/grammar/def_spec.rb +60 -0
  243. data/spec/grammar/false_spec.rb +17 -0
  244. data/spec/grammar/file_spec.rb +7 -0
  245. data/spec/grammar/gvar_spec.rb +13 -0
  246. data/spec/grammar/hash_spec.rb +17 -0
  247. data/spec/grammar/iasgn_spec.rb +9 -0
  248. data/spec/grammar/if_spec.rb +26 -0
  249. data/spec/grammar/iter_spec.rb +59 -0
  250. data/spec/grammar/ivar_spec.rb +9 -0
  251. data/spec/grammar/lasgn_spec.rb +8 -0
  252. data/spec/grammar/line_spec.rb +8 -0
  253. data/spec/grammar/lvar_spec.rb +38 -0
  254. data/spec/grammar/module_spec.rb +27 -0
  255. data/spec/grammar/nil_spec.rb +17 -0
  256. data/spec/grammar/not_spec.rb +27 -0
  257. data/spec/grammar/op_asgn1_spec.rb +23 -0
  258. data/spec/grammar/op_asgn2_spec.rb +23 -0
  259. data/spec/grammar/or_spec.rb +13 -0
  260. data/spec/grammar/return_spec.rb +17 -0
  261. data/spec/grammar/sclass_spec.rb +20 -0
  262. data/spec/grammar/self_spec.rb +17 -0
  263. data/spec/grammar/str_spec.rb +96 -0
  264. data/spec/grammar/super_spec.rb +20 -0
  265. data/spec/grammar/true_spec.rb +17 -0
  266. data/spec/grammar/undef_spec.rb +15 -0
  267. data/spec/grammar/unless_spec.rb +13 -0
  268. data/spec/grammar/while_spec.rb +15 -0
  269. data/spec/grammar/xstr_spec.rb +116 -0
  270. data/spec/grammar/yield_spec.rb +20 -0
  271. data/spec/spec_helper.rb +9 -0
  272. metadata +346 -21
  273. data/lib/opal/bundle.rb +0 -34
  274. data/lib/opal/lexer.rb +0 -902
  275. data/lib/opal/nodes.rb +0 -2150
  276. data/lib/opal/parser.rb +0 -4894
  277. data/lib/opal/rake/bundle_task.rb +0 -63
  278. data/opal-parser.js +0 -8343
  279. data/stdlib/strscan.rb +0 -52
  280. data/templates/init/Rakefile +0 -7
  281. data/templates/init/index.html +0 -17
  282. data/templates/init/lib/__NAME__.rb +0 -2
@@ -0,0 +1,80 @@
1
+ # NOTE: our next/peek/rewind implementation is REALLY slow
2
+
3
+ class Enumerator
4
+ include Enumerable
5
+
6
+ class Yielder
7
+ def initialize (block)
8
+ @block = block
9
+ end
10
+
11
+ def call (block)
12
+ @call = block
13
+
14
+ @block.call
15
+ end
16
+
17
+ def yield (value)
18
+ @call.call(value)
19
+ end
20
+
21
+ alias_method :<<, :yield
22
+ end
23
+
24
+ class Generator
25
+ attr_reader :enumerator
26
+
27
+ def initialize (block)
28
+ @yielder = Yielder.new(block)
29
+ end
30
+
31
+ def each (&block)
32
+ @yielder.call(block)
33
+ end
34
+ end
35
+
36
+ def initialize (object = nil, method = :each, *args, &block)
37
+ if block_given?
38
+ @object = Generator.new(block)
39
+ method = :each
40
+ end
41
+
42
+ raise ArgumentError, 'wrong number of argument (0 for 1+)' unless object
43
+
44
+ @object = object
45
+ @method = method
46
+ @args = args
47
+
48
+ @current = 0
49
+ end
50
+
51
+ def next
52
+ end
53
+
54
+ def each (&block)
55
+ return self unless block
56
+
57
+ @object.__send__ @method, *args, &block
58
+ end
59
+
60
+ def each_with_index (&block)
61
+ with_index &block
62
+ end
63
+
64
+ def with_index (offset = 0, &block)
65
+ return Enumerator.new(self, :with_index, offset) unless block
66
+ end
67
+
68
+ def with_object (object, &block)
69
+ return Enumerator.new(self, :with_object, object) unless block
70
+
71
+ end
72
+ end
73
+
74
+ module Kernel
75
+ def enum_for (method = :each, *args)
76
+ Enumerator.new(self, method, *args)
77
+ end
78
+
79
+ alias_method :to_enum, :enum_for
80
+ end
@@ -0,0 +1,25 @@
1
+ class Exception
2
+ def initialize(message = '')
3
+ %x{
4
+ if (Error.captureStackTrace) {
5
+ Error.captureStackTrace(this);
6
+ }
7
+
8
+ this.message = message;
9
+ }
10
+ end
11
+
12
+ def backtrace
13
+ `this._bt || (this._bt = exc_backtrace(this))`
14
+ end
15
+
16
+ def inspect
17
+ "#<#{self.class}: '#{message}'>"
18
+ end
19
+
20
+ def message
21
+ `this.message`
22
+ end
23
+
24
+ alias_method :to_s, :message
25
+ end
@@ -0,0 +1,80 @@
1
+ class File
2
+ def self.expand_path(path, base = undefined)
3
+ %x{
4
+ if (!base) {
5
+ if (path.charAt(0) !== '/') {
6
+ base = FS_CWD;
7
+ }
8
+ else {
9
+ base = '';
10
+ }
11
+ }
12
+
13
+ path = #{ join(base, path) };
14
+
15
+ var parts = path.split('/'), result = [], path;
16
+
17
+ // initial '/'
18
+ if (parts[0] === '') {
19
+ result.push('');
20
+ }
21
+
22
+ for (var i = 0, ii = parts.length; i < ii; i++) {
23
+ part = parts[i];
24
+
25
+ if (part === '..') {
26
+ result.pop();
27
+ }
28
+ else if (part === '.' || part === '') {
29
+
30
+ }
31
+ else {
32
+ result.push(part);
33
+ }
34
+ }
35
+
36
+ return result.join('/');
37
+ }
38
+ end
39
+
40
+ def self.join(*paths)
41
+ `paths.join('/')`
42
+ end
43
+
44
+ def self.dirname(path)
45
+ %x{
46
+ var dirname = PATH_RE.exec(path)[1];
47
+
48
+ if (!dirname) {
49
+ return '.';
50
+ }
51
+ else if (dirname === '/') {
52
+ return dirname;
53
+ }
54
+ else {
55
+ return dirname.substring(0, dirname.length - 1);
56
+ }
57
+ }
58
+ end
59
+
60
+ def self.extname(path)
61
+ %x{
62
+ var extname = PATH_RE.exec(path)[3];
63
+
64
+ if (!extname || extname === '.') {
65
+ return '';
66
+ }
67
+ else {
68
+ return extname;
69
+ }
70
+ }
71
+ end
72
+
73
+ def self.basename(path, suffix)
74
+ `$opal.fs.basename(path, suffix)`
75
+ end
76
+
77
+ def self.exist?(path)
78
+ `opal.loader.factories[#{ expand_path path }] ? true : false`
79
+ end
80
+ end
@@ -0,0 +1,503 @@
1
+ class Hash
2
+ include Enumerable
3
+
4
+ def self.[](*objs)
5
+ `$opal.hash.apply(null, objs)`
6
+ end
7
+
8
+ def self.allocate
9
+ `new $opal.hash()`
10
+ end
11
+
12
+ def self.new(defaults = undefined, &block)
13
+ %x{
14
+ var hash = new $opal.hash();
15
+
16
+ if (defaults !== undefined) {
17
+ hash.none = defaults;
18
+ }
19
+ else if (block !== nil) {
20
+ hash.proc = block;
21
+ }
22
+
23
+ return hash;
24
+ }
25
+ end
26
+
27
+ def ==(other)
28
+ %x{
29
+ if (this === other) {
30
+ return true;
31
+ }
32
+
33
+ if (!other.map) {
34
+ return false;
35
+ }
36
+
37
+ var map = this.map,
38
+ map2 = other.map;
39
+
40
+ for (var assoc in map) {
41
+ if (!map2[assoc]) {
42
+ return false;
43
+ }
44
+
45
+ var obj = map[assoc][1],
46
+ obj2 = map2[assoc][1];
47
+
48
+ if (#{`obj` != `obj2`}) {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ return true;
54
+ }
55
+ end
56
+
57
+ def [](key)
58
+ %x{
59
+ var hash = #{key.hash},
60
+ bucket;
61
+
62
+ if (bucket = this.map[hash]) {
63
+ return bucket[1];
64
+ }
65
+
66
+ return this.none;
67
+ }
68
+ end
69
+
70
+ def []=(key, value)
71
+ %x{
72
+ var hash = #{key.hash};
73
+ this.map[hash] = [key, value];
74
+
75
+ return value;
76
+ }
77
+ end
78
+
79
+ def assoc(object)
80
+ %x{
81
+ for (var assoc in this.map) {
82
+ var bucket = this.map[assoc];
83
+
84
+ if (#{`bucket[0]` == `object`}) {
85
+ return [bucket[0], bucket[1]];
86
+ }
87
+ }
88
+
89
+ return nil;
90
+ }
91
+ end
92
+
93
+ def clear
94
+ %x{
95
+ this.map = {};
96
+
97
+ return this;
98
+ }
99
+ end
100
+
101
+ def clone
102
+ %x{
103
+ var result = new $opal.hash(),
104
+ map = this.map,
105
+ map2 = result.map;
106
+
107
+ for (var assoc in map) {
108
+ map2[assoc] = [map[assoc][0], map[assoc][1]];
109
+ }
110
+
111
+ return result;
112
+ }
113
+ end
114
+
115
+ def default
116
+ `this.none`
117
+ end
118
+
119
+ def default=(object)
120
+ `this.none = object`
121
+ end
122
+
123
+ def default_proc
124
+ `this.proc`
125
+ end
126
+
127
+ def default_proc=(proc)
128
+ `this.proc = proc`
129
+ end
130
+
131
+ def delete(key)
132
+ %x{
133
+ var map = this.map,
134
+ hash = #{key.hash},
135
+ result;
136
+
137
+ if (result = map[hash]) {
138
+ result = bucket[1];
139
+
140
+ delete map[hash];
141
+ }
142
+
143
+ return result;
144
+ }
145
+ end
146
+
147
+ def delete_if(&block)
148
+ return enum_for :delete_if unless block_given?
149
+
150
+ %x{
151
+ var map = this.map;
152
+
153
+ for (var assoc in map) {
154
+ var bucket = map[assoc],
155
+ value;
156
+
157
+ if ((value = $yield.call($context, null, bucket[0], bucket[1])) === $breaker) {
158
+ return $breaker.$v;
159
+ }
160
+
161
+ if (value !== false && value !== nil) {
162
+ delete map[assoc];
163
+ }
164
+ }
165
+
166
+ return this;
167
+ }
168
+ end
169
+
170
+ def each(&block)
171
+ return enum_for :each unless block_given?
172
+
173
+ %x{
174
+ var map = this.map;
175
+
176
+ for (var assoc in map) {
177
+ var bucket = map[assoc];
178
+
179
+ if ($yield.call($context, null, bucket[0], bucket[1]) === $breaker) {
180
+ return $breaker.$v;
181
+ }
182
+ }
183
+
184
+ return this;
185
+ }
186
+ end
187
+
188
+ def each_key(&block)
189
+ return enum_for :each_key unless block_given?
190
+
191
+ %x{
192
+ var map = this.map;
193
+
194
+ for (var assoc in map) {
195
+ var bucket = map[assoc];
196
+
197
+ if ($yield.call($context, null, bucket[0]) === $breaker) {
198
+ return $breaker.$v;
199
+ }
200
+ }
201
+
202
+ return this;
203
+ }
204
+ end
205
+
206
+ alias_method :each_pair, :each
207
+
208
+ def each_value(&block)
209
+ return enum_for :each_value unless block_given?
210
+
211
+ %x{
212
+ var map = this.map;
213
+
214
+ for (var assoc in map) {
215
+ var bucket = map[assoc];
216
+
217
+ if ($yield.call($context, null, bucket[1]) === $breaker) {
218
+ return $breaker.$v;
219
+ }
220
+ }
221
+
222
+ return this;
223
+ }
224
+ end
225
+
226
+ def empty?
227
+ %x{
228
+ for (var assoc in this.map) {
229
+ return false;
230
+ }
231
+
232
+ return true;
233
+ }
234
+ end
235
+
236
+ alias_method :eql?, :==
237
+
238
+ def fetch(key, defaults = undefined, &block)
239
+ %x{
240
+ var bucket = this.map[#{key.hash}];
241
+
242
+ if (block !== nil) {
243
+ var value;
244
+
245
+ if ((value = $yield.call($context, null, key)) === $breaker) {
246
+ return $breaker.$v;
247
+ }
248
+
249
+ return value;
250
+ }
251
+
252
+ if (defaults !== undefined) {
253
+ return defaults;
254
+ }
255
+
256
+ raise(RubyKeyError, 'key not found');
257
+ }
258
+ end
259
+
260
+ def flatten(level = undefined)
261
+ %x{
262
+ var map = this.map,
263
+ result = [];
264
+
265
+ for (var assoc in map) {
266
+ var bucket = map[assoc],
267
+ key = bucket[0],
268
+ value = bucket[1];
269
+
270
+ result.push(key);
271
+
272
+ if (value.$flags & T_ARRAY) {
273
+ if (level === undefined || level === 1) {
274
+ result.push(value);
275
+ }
276
+ else {
277
+ result = result.concat(#{value.flatten(level - 1)});
278
+ }
279
+ }
280
+ else {
281
+ result.push(value);
282
+ }
283
+ }
284
+
285
+ return result;
286
+ }
287
+ end
288
+
289
+ def has_key?(key)
290
+ `!!this.map[#{key.hash}]`
291
+ end
292
+
293
+ def has_value?(value)
294
+ %x{
295
+ for (var assoc in this.map) {
296
+ if (#{`this.map[assoc][1]` == value}) {
297
+ return true;
298
+ }
299
+ }
300
+
301
+ return false;
302
+ }
303
+ end
304
+
305
+ def hash
306
+ `this.$id`
307
+ end
308
+
309
+ def inspect
310
+ %x{
311
+ var inspect = [],
312
+ map = this.map;
313
+
314
+ for (var assoc in map) {
315
+ var bucket = map[assoc];
316
+
317
+ inspect.push(#{`bucket[0]`.inspect} + '=>' + #{`bucket[1]`.inspect});
318
+ }
319
+ return '{' + inspect.join(', ') + '}';
320
+ }
321
+ end
322
+
323
+ def invert
324
+ %x{
325
+ var result = $opal.hash(),
326
+ map = this.map,
327
+ map2 = result.map;
328
+
329
+ for (var assoc in map) {
330
+ var bucket = map[assoc];
331
+
332
+ map2[#{`bucket[1]`.hash}] = [bucket[0], bucket[1]];
333
+ }
334
+
335
+ return result;
336
+ }
337
+ end
338
+
339
+ def key(object)
340
+ %x{
341
+ for (var assoc in this.map) {
342
+ var bucket = this.map[assoc];
343
+
344
+ if (#{object == `bucket[1]`}) {
345
+ return bucket[0];
346
+ }
347
+ }
348
+
349
+ return nil;
350
+ }
351
+ end
352
+
353
+ alias_method :key?, :has_key?
354
+
355
+ def keys
356
+ %x{
357
+ var result = [];
358
+
359
+ for (var assoc in this.map) {
360
+ result.push(this.map[assoc][0]);
361
+ }
362
+
363
+ return result;
364
+ }
365
+ end
366
+
367
+ def length
368
+ %x{
369
+ var result = 0;
370
+
371
+ for (var assoc in this.map) {
372
+ result++;
373
+ }
374
+
375
+ return result;
376
+ }
377
+ end
378
+
379
+ alias_method :member?, :has_key?
380
+
381
+ def merge(other)
382
+ %x{
383
+ var result = $opal.hash(),
384
+ map = this.map,
385
+ map2 = result.map;
386
+
387
+ for (var assoc in map) {
388
+ var bucket = map[assoc];
389
+
390
+ map2[assoc] = [bucket[0], bucket[1]];
391
+ }
392
+
393
+ map = other.map;
394
+
395
+ for (var assoc in map) {
396
+ var bucket = map[assoc];
397
+
398
+ map2[assoc] = [bucket[0], bucket[1]];
399
+ }
400
+
401
+ return result;
402
+ }
403
+ end
404
+
405
+ def merge!(other)
406
+ %x{
407
+ var map = this.map,
408
+ map2 = other.map;
409
+
410
+ for (var assoc in map2) {
411
+ var bucket = map2[assoc];
412
+
413
+ map[assoc] = [bucket[0], bucket[1]];
414
+ }
415
+
416
+ return this;
417
+ }
418
+ end
419
+
420
+ def rassoc(object)
421
+ %x{
422
+ var map = this.map;
423
+
424
+ for (var assoc in map) {
425
+ var bucket = map[assoc];
426
+
427
+ if (#{`bucket[1]` == object}) {
428
+ return [bucket[0], bucket[1]];
429
+ }
430
+ }
431
+
432
+ return nil;
433
+ }
434
+ end
435
+
436
+ def replace(other)
437
+ %x{
438
+ var map = this.map = {};
439
+
440
+ for (var assoc in other.map) {
441
+ var bucket = other.map[assoc];
442
+
443
+ map[assoc] = [bucket[0], bucket[1]];
444
+ }
445
+
446
+ return this;
447
+ }
448
+ end
449
+
450
+ alias_method :size, :length
451
+
452
+ def to_a
453
+ %x{
454
+ var map = this.map,
455
+ result = [];
456
+
457
+ for (var assoc in map) {
458
+ var bucket = map[assoc];
459
+
460
+ result.push([bucket[0], bucket[1]]);
461
+ }
462
+
463
+ return result;
464
+ }
465
+ end
466
+
467
+ def to_hash
468
+ self
469
+ end
470
+
471
+ def to_native
472
+ %x{
473
+ var map = this.map,
474
+ result = {};
475
+
476
+ for (var assoc in map) {
477
+ var key = map[assoc][0],
478
+ value = map[assoc][1];
479
+
480
+ result[key] = #{Opal.object?(`value`) ? `value`.to_native : `value`};
481
+ }
482
+
483
+ return result;
484
+ }
485
+ end
486
+
487
+ alias_method :to_s, :inspect
488
+
489
+ alias_method :update, :merge!
490
+
491
+ def values
492
+ %x{
493
+ var map = this.map,
494
+ result = [];
495
+
496
+ for (var assoc in map) {
497
+ result.push(map[assoc][1]);
498
+ }
499
+
500
+ return result;
501
+ }
502
+ end
503
+ end