opal 0.6.3 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.spectator +2 -0
  4. data/.spectator-mspec +3 -0
  5. data/.travis.yml +8 -11
  6. data/CHANGELOG.md +33 -0
  7. data/CONTRIBUTING.md +8 -43
  8. data/Gemfile +15 -4
  9. data/Guardfile +77 -0
  10. data/README.md +15 -9
  11. data/Rakefile +36 -12
  12. data/benchmarks/operators.rb +11 -0
  13. data/bin/opal +10 -13
  14. data/bin/opal-build +4 -4
  15. data/bin/opal-mspec +10 -0
  16. data/bin/opal-repl +4 -3
  17. data/examples/sinatra/Gemfile +1 -1
  18. data/examples/sinatra/config.ru +3 -3
  19. data/lib/mspec/opal/main.rb.erb +2 -2
  20. data/lib/mspec/opal/rake_task.rb +31 -24
  21. data/lib/mspec/opal/runner.rb +18 -1
  22. data/lib/mspec/opal/sprockets.js +17 -0
  23. data/lib/opal.rb +1 -34
  24. data/lib/opal/builder.rb +92 -58
  25. data/lib/opal/builder_processors.rb +165 -0
  26. data/lib/opal/cli.rb +85 -144
  27. data/lib/opal/cli_options.rb +136 -90
  28. data/lib/opal/cli_runners.rb +10 -0
  29. data/lib/opal/cli_runners/nodejs.rb +56 -0
  30. data/lib/opal/cli_runners/phantom.js +35 -0
  31. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  32. data/lib/opal/cli_runners/server.rb +54 -0
  33. data/lib/opal/compiler.rb +35 -16
  34. data/lib/opal/erb.rb +29 -15
  35. data/lib/opal/hike_path_finder.rb +18 -0
  36. data/lib/opal/nodes.rb +1 -0
  37. data/lib/opal/nodes/call.rb +107 -26
  38. data/lib/opal/nodes/call_special.rb +31 -6
  39. data/lib/opal/nodes/class.rb +2 -2
  40. data/lib/opal/nodes/constants.rb +5 -20
  41. data/lib/opal/nodes/def.rb +4 -4
  42. data/lib/opal/nodes/defined.rb +3 -3
  43. data/lib/opal/nodes/definitions.rb +1 -1
  44. data/lib/opal/nodes/for.rb +35 -0
  45. data/lib/opal/nodes/helpers.rb +2 -2
  46. data/lib/opal/nodes/iter.rb +3 -3
  47. data/lib/opal/nodes/literal.rb +10 -2
  48. data/lib/opal/nodes/masgn.rb +2 -2
  49. data/lib/opal/nodes/module.rb +2 -2
  50. data/lib/opal/nodes/scope.rb +1 -0
  51. data/lib/opal/nodes/singleton_class.rb +2 -2
  52. data/lib/opal/nodes/super.rb +2 -2
  53. data/lib/opal/nodes/top.rb +30 -3
  54. data/lib/opal/parser.rb +15 -1
  55. data/lib/opal/parser/grammar.rb +2571 -2452
  56. data/lib/opal/parser/grammar.y +37 -5
  57. data/lib/opal/parser/keywords.rb +2 -0
  58. data/lib/opal/parser/lexer.rb +21 -11
  59. data/lib/opal/path_reader.rb +28 -0
  60. data/lib/opal/paths.rb +38 -0
  61. data/lib/opal/source_map.rb +32 -15
  62. data/lib/opal/sprockets/environment.rb +9 -2
  63. data/lib/opal/sprockets/erb.rb +1 -2
  64. data/lib/opal/sprockets/path_reader.rb +34 -0
  65. data/lib/opal/sprockets/processor.rb +40 -39
  66. data/lib/opal/sprockets/server.rb +47 -33
  67. data/lib/opal/version.rb +1 -1
  68. data/opal.gemspec +10 -5
  69. data/opal/README.md +6 -0
  70. data/opal/corelib/array.rb +36 -4
  71. data/opal/corelib/array/inheritance.rb +6 -6
  72. data/opal/corelib/basic_object.rb +9 -9
  73. data/opal/corelib/boolean.rb +1 -1
  74. data/opal/corelib/class.rb +12 -12
  75. data/opal/corelib/dir.rb +20 -0
  76. data/opal/corelib/enumerable.rb +42 -42
  77. data/opal/corelib/enumerator.rb +1 -1
  78. data/opal/corelib/error.rb +2 -2
  79. data/opal/corelib/file.rb +56 -0
  80. data/opal/corelib/hash.rb +5 -5
  81. data/opal/corelib/helpers.rb +3 -3
  82. data/opal/corelib/io.rb +13 -10
  83. data/opal/corelib/kernel.rb +44 -68
  84. data/opal/corelib/method.rb +1 -1
  85. data/opal/corelib/module.rb +89 -114
  86. data/opal/corelib/nil_class.rb +1 -1
  87. data/opal/corelib/numeric.rb +27 -23
  88. data/opal/corelib/proc.rb +5 -5
  89. data/opal/corelib/range.rb +8 -4
  90. data/opal/corelib/regexp.rb +5 -5
  91. data/opal/corelib/runtime.js +589 -272
  92. data/opal/corelib/string.rb +52 -37
  93. data/opal/corelib/string/inheritance.rb +5 -5
  94. data/opal/corelib/time.rb +102 -52
  95. data/opal/corelib/variables.rb +3 -3
  96. data/opal/opal.rb +2 -0
  97. data/package.json +9 -0
  98. data/spec/filters/bugs/array.rb +0 -6
  99. data/spec/filters/bugs/language.rb +4 -0
  100. data/spec/filters/bugs/numeric.rb +7 -6
  101. data/spec/filters/bugs/opal.rb +2 -0
  102. data/spec/filters/bugs/regexp.rb +4 -0
  103. data/spec/filters/bugs/string.rb +0 -7
  104. data/spec/filters/bugs/stringscanner.rb +4 -1
  105. data/spec/filters/unsupported/private_methods.rb +2 -0
  106. data/spec/lib/builder_processors_spec.rb +27 -0
  107. data/spec/lib/builder_spec.rb +66 -0
  108. data/spec/{cli → lib}/cli_spec.rb +60 -5
  109. data/spec/{cli → lib}/compiler_spec.rb +66 -5
  110. data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
  111. data/spec/lib/fixtures/no_requires.rb +1 -0
  112. data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
  113. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  114. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  115. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  116. data/spec/lib/fixtures/requires.rb +7 -0
  117. data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
  118. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  119. data/spec/lib/hike_path_finder_spec.rb +23 -0
  120. data/spec/{cli → lib}/lexer_spec.rb +1 -1
  121. data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
  122. data/spec/{cli → lib}/parser/and_spec.rb +1 -1
  123. data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
  124. data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
  125. data/spec/{cli → lib}/parser/block_spec.rb +1 -1
  126. data/spec/{cli → lib}/parser/break_spec.rb +1 -1
  127. data/spec/{cli → lib}/parser/call_spec.rb +1 -1
  128. data/spec/{cli → lib}/parser/class_spec.rb +1 -1
  129. data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
  130. data/spec/{cli → lib}/parser/def_spec.rb +1 -1
  131. data/spec/{cli → lib}/parser/if_spec.rb +1 -1
  132. data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
  133. data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
  134. data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
  135. data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
  136. data/spec/{cli → lib}/parser/module_spec.rb +1 -1
  137. data/spec/{cli → lib}/parser/not_spec.rb +1 -1
  138. data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
  139. data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
  140. data/spec/{cli → lib}/parser/or_spec.rb +1 -1
  141. data/spec/{cli → lib}/parser/return_spec.rb +1 -1
  142. data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
  143. data/spec/{cli → lib}/parser/string_spec.rb +8 -1
  144. data/spec/{cli → lib}/parser/super_spec.rb +1 -1
  145. data/spec/lib/parser/unary_spec.rb +48 -0
  146. data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
  147. data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
  148. data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
  149. data/spec/{cli → lib}/parser/while_spec.rb +1 -1
  150. data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
  151. data/spec/lib/path_reader_spec.rb +24 -0
  152. data/spec/lib/shared/path_finder_shared.rb +19 -0
  153. data/spec/lib/shared/path_reader_shared.rb +31 -0
  154. data/spec/lib/spec_helper.rb +9 -0
  155. data/spec/lib/sprockets/environment_spec.rb +30 -0
  156. data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
  157. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  158. data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
  159. data/spec/lib/sprockets/server_spec.rb +20 -0
  160. data/spec/opal/compiler/irb_spec.rb +11 -11
  161. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  162. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  163. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  164. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  165. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  166. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  167. data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
  168. data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
  169. data/spec/opal/core/source_map_spec.rb +2 -2
  170. data/spec/opal/core/string_spec.rb +11 -0
  171. data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
  172. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  173. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  174. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  175. data/spec/rubyspecs +54 -11
  176. data/spec/spec_helper.rb +18 -3
  177. data/spec/support/mspec_rspec_adapter.rb +33 -0
  178. data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
  179. data/stdlib/README.md +3 -0
  180. data/stdlib/benchmark.rb +10 -0
  181. data/stdlib/date.rb +2 -2
  182. data/stdlib/dir.rb +1 -5
  183. data/stdlib/file.rb +1 -7
  184. data/stdlib/json.rb +10 -1
  185. data/stdlib/native.rb +5 -5
  186. data/stdlib/nodejs.rb +5 -0
  187. data/stdlib/nodejs/dir.rb +13 -0
  188. data/stdlib/nodejs/file.rb +98 -0
  189. data/stdlib/nodejs/fileutils.rb +26 -0
  190. data/stdlib/nodejs/io.rb +2 -0
  191. data/stdlib/nodejs/irb.rb +45 -0
  192. data/stdlib/nodejs/process.rb +16 -0
  193. data/stdlib/nodejs/require.rb +32 -0
  194. data/stdlib/nodejs/rubygems.rb +68 -0
  195. data/stdlib/nodejs/runtime.rb +25 -0
  196. data/stdlib/nodejs/yaml.rb +11 -0
  197. data/stdlib/opal-parser.rb +1 -2
  198. data/stdlib/opal-source-maps.rb +2 -0
  199. data/stdlib/phantomjs.rb +8 -0
  200. data/stdlib/process.rb +10 -0
  201. data/stdlib/promise.rb +12 -4
  202. data/stdlib/set.rb +27 -0
  203. data/stdlib/source_map.rb +5 -63
  204. data/stdlib/source_map/map.rb +220 -0
  205. data/stdlib/source_map/mapping.rb +26 -0
  206. data/stdlib/source_map/offset.rb +88 -0
  207. data/stdlib/source_map/version.rb +3 -0
  208. data/stdlib/source_map/vlq.rb +77 -101
  209. data/stdlib/sourcemap.rb +1 -0
  210. data/stdlib/strscan.rb +7 -1
  211. data/stdlib/template.rb +1 -1
  212. data/stdlib/thread.rb +147 -7
  213. metadata +238 -104
  214. data/lib/mspec/opal/mspec_fixes.rb +0 -87
  215. data/spec/cli/sprockets/environment_spec.rb +0 -14
  216. data/spec/filters/bugs/symbol.rb +0 -5
  217. data/spec/opal/core/kernel/warn_spec.rb +0 -83
  218. data/spec/opal/core/language/numbers_spec.rb +0 -60
  219. data/stdlib/opal-source-maps.js.erb +0 -2
  220. data/stdlib/source_map/generator.rb +0 -251
  221. data/stdlib/source_map/parser.rb +0 -102
@@ -0,0 +1,26 @@
1
+ require 'source_map/offset'
2
+
3
+ module SourceMap
4
+ class Mapping < Struct.new(:source, :generated, :original, :name)
5
+ # Public: Get a simple string representation of the mapping.
6
+ #
7
+ # Returns a String.
8
+ def to_s
9
+ str = "#{generated.line}:#{generated.column}"
10
+ str << "->#{source}@#{original.line}:#{original.column}"
11
+ str << "##{name}" if name
12
+ str
13
+ end
14
+
15
+ # Public: Get a pretty inspect output for debugging purposes.
16
+ #
17
+ # Returns a String.
18
+ def inspect
19
+ str = "#<#{self.class} source=#{source.inspect}"
20
+ str << " generated=#{generated}, original=#{original}"
21
+ str << " name=#{name.inspect}" if name
22
+ str << ">"
23
+ str
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,88 @@
1
+ module SourceMap
2
+ # Public: Offset is an immutable structure representing a position in
3
+ # a source file.
4
+ class Offset
5
+ include Comparable
6
+
7
+ # Public: Construct Offset value.
8
+ #
9
+ # Returns Offset instance.
10
+ def self.new(*args)
11
+ case args.first
12
+ when Offset
13
+ args.first
14
+ when Array
15
+ super(*args.first)
16
+ else
17
+ super(*args)
18
+ end
19
+ end
20
+
21
+ # Public: Initialize an Offset.
22
+ #
23
+ # line - Integer line number
24
+ # column - Integer column number
25
+ def initialize(line, column)
26
+ @line, @column = line, column
27
+ end
28
+
29
+ # Public: Gets Integer line of offset
30
+ attr_reader :line
31
+
32
+ # Public: Get Integer column of offset
33
+ attr_reader :column
34
+
35
+ # Public: Shift the offset by some value.
36
+ #
37
+ # other - An Offset to add by its line and column
38
+ # Or an Integer to add by line
39
+ #
40
+ # Returns a new Offset instance.
41
+ def +(other)
42
+ case other
43
+ when Offset
44
+ Offset.new(self.line + other.line, self.column + other.column)
45
+ when Integer
46
+ Offset.new(self.line + other, self.column)
47
+ else
48
+ raise ArgumentError, "can't convert #{other} into #{self.class}"
49
+ end
50
+ end
51
+
52
+ # Public: Compare Offset to another.
53
+ #
54
+ # Useful for determining if a position in a few is between two offsets.
55
+ #
56
+ # other - Another Offset
57
+ #
58
+ # Returns a negative number when other is smaller and a positive number
59
+ # when its greater. Implements the Comparable#<=> protocol.
60
+ def <=>(other)
61
+ case other
62
+ when Offset
63
+ diff = self.line - other.line
64
+ diff.zero? ? self.column - other.column : diff
65
+ else
66
+ raise ArgumentError, "can't convert #{other.class} into #{self.class}"
67
+ end
68
+ end
69
+
70
+ # Public: Get a simple string representation of the offset
71
+ #
72
+ # Returns a String.
73
+ def to_s
74
+ if column == 0
75
+ "#{line}"
76
+ else
77
+ "#{line}:#{column}"
78
+ end
79
+ end
80
+
81
+ # Public: Get a pretty inspect output for debugging purposes.
82
+ #
83
+ # Returns a String.
84
+ def inspect
85
+ "#<#{self.class} line=#{line}, column=#{column}>"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,3 @@
1
+ module SourceMap
2
+ VERSION = "0.0.2"
3
+ end
@@ -1,122 +1,98 @@
1
- class SourceMap
2
- # Support for encoding/decoding the variable length quantity format
3
- # described in the spec at:
1
+ module SourceMap
2
+ # Public: Base64 VLQ encoding
4
3
  #
5
- # https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
4
+ # Adopted from ConradIrwin/ruby-source_map
5
+ # https://github.com/ConradIrwin/ruby-source_map/blob/master/lib/source_map/vlq.rb
6
6
  #
7
- # This implementation is heavily based on https://github.com/mozilla/source-map
8
- # Copyright 2009-2011, Mozilla Foundation and contributors, BSD
7
+ # Resources
8
+ #
9
+ # http://en.wikipedia.org/wiki/Variable-length_quantity
10
+ # https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
11
+ # https://github.com/mozilla/source-map/blob/master/lib/source-map/base64-vlq.js
9
12
  #
10
13
  module VLQ
11
-
12
- # A single base 64 digit can contain 6 bits of data. For the base 64 variable
13
- # length quantities we use in the source map spec, the first bit is the sign,
14
- # the next four bits are the actual value, and the 6th bit is the
15
- # continuation bit. The continuation bit tells us whether there are more
16
- # digits in this value following this digit.
17
- #
18
- # Continuation
19
- # | Sign
20
- # | |
21
- # V V
22
- # 101011
23
-
24
- VLQ_BASE_SHIFT = 5;
25
-
26
- # binary: 100000
27
- VLQ_BASE = 1 << VLQ_BASE_SHIFT;
28
-
29
- # binary: 011111
30
- VLQ_BASE_MASK = VLQ_BASE - 1;
31
-
32
- # binary: 100000
33
- VLQ_CONTINUATION_BIT = VLQ_BASE;
14
+ VLQ_BASE_SHIFT = 5
15
+ VLQ_BASE = 1 << VLQ_BASE_SHIFT
16
+ VLQ_BASE_MASK = VLQ_BASE - 1
17
+ VLQ_CONTINUATION_BIT = VLQ_BASE
34
18
 
35
19
  BASE64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('')
36
- BASE64_VALUES = (0..64).inject({}){ |h, i| h.update BASE64_DIGITS[i] => i }
37
-
38
- # Returns the base 64 VLQ encoded value.
39
- def self.encode(int)
20
+ BASE64_VALUES = (0...64).inject({}) { |h, i| h[BASE64_DIGITS[i]] = i; h }
40
21
 
41
- vlq = to_vlq_signed(int)
42
- encoded = []
43
-
44
- begin
45
- digit = vlq & VLQ_BASE_MASK
46
- vlq >>= VLQ_BASE_SHIFT
47
- digit |= VLQ_CONTINUATION_BIT if vlq > 0
48
- encoded << base64_encode(digit)
49
- end while vlq > 0
50
-
51
- encoded.join
22
+ # Public: Encode a list of numbers into a compact VLQ string.
23
+ #
24
+ # ary - An Array of Integers
25
+ #
26
+ # Returns a VLQ String.
27
+ def self.encode(ary)
28
+ result = []
29
+ ary.each do |n|
30
+ vlq = n < 0 ? ((-n) << 1) + 1 : n << 1
31
+ begin
32
+ digit = vlq & VLQ_BASE_MASK
33
+ vlq >>= VLQ_BASE_SHIFT
34
+ digit |= VLQ_CONTINUATION_BIT if vlq > 0
35
+ result << BASE64_DIGITS[digit]
36
+ end while vlq > 0
37
+ end
38
+ result.join
52
39
  end
53
40
 
54
- # Decodes the next base 64 VLQ value from the given string and returns the
55
- # value and the rest of the string.
41
+ # Public: Decode a VLQ string.
42
+ #
43
+ # str - VLQ encoded String
44
+ #
45
+ # Returns an Array of Integers.
56
46
  def self.decode(str)
57
-
58
- vlq = 0
59
- shift = 0
60
- continue = true
47
+ result = []
61
48
  chars = str.split('')
62
-
63
- while continue
64
- char = chars.shift or raise "Expected more digits in base 64 VLQ value."
65
- digit = base64_decode(char)
66
- continue = false if (digit & VLQ_CONTINUATION_BIT) == 0
67
- digit &= VLQ_BASE_MASK
68
- vlq += digit << shift
69
- shift += VLQ_BASE_SHIFT
70
- end
71
-
72
- [from_vlq_signed(vlq), chars.join('')]
73
- end
74
-
75
- # Decode an array of variable length quantities from the given string and
76
- # return them.
77
- def self.decode_array(str)
78
- output = []
79
- while str != ''
80
- int, str = decode(str)
81
- output << int
49
+ while chars.any?
50
+ vlq = 0
51
+ shift = 0
52
+ continuation = true
53
+ while continuation
54
+ char = chars.shift
55
+ raise ArgumentError unless char
56
+ digit = BASE64_VALUES[char]
57
+ continuation = false if (digit & VLQ_CONTINUATION_BIT) == 0
58
+ digit &= VLQ_BASE_MASK
59
+ vlq += digit << shift
60
+ shift += VLQ_BASE_SHIFT
61
+ end
62
+ result << (vlq & 1 == 1 ? -(vlq >> 1) : vlq >> 1)
82
63
  end
83
- output
84
- end
85
-
86
- protected
87
-
88
- def self.base64_encode(int)
89
- BASE64_DIGITS[int] or raise ArgumentError, "#{int} is not a valid base64 digit"
64
+ result
90
65
  end
91
66
 
92
- def self.base64_decode(char)
93
- BASE64_VALUES[char] or raise ArgumentError, "#{char} is not a valid base64 digit"
94
- end
95
-
96
- # Converts from a two's-complement integer to an integer where the
97
- # sign bit is placed in the least significant bit. For example, as decimals:
98
- # 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
99
- # 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
100
- def self.to_vlq_signed(int)
101
- if int < 0
102
- ((-int) << 1) + 1
103
- else
104
- int << 1
105
- end
67
+ # Public: Encode a mapping array into a compact VLQ string.
68
+ #
69
+ # ary - Two dimensional Array of Integers.
70
+ #
71
+ # Returns a VLQ encoded String seperated by , and ;.
72
+ def self.encode_mappings(ary)
73
+ ary.map { |group|
74
+ group.map { |segment|
75
+ encode(segment)
76
+ }.join(',')
77
+ }.join(';')
106
78
  end
107
79
 
108
- # Converts to a two's-complement value from a value where the sign bit is
109
- # placed in the least significant bit. For example, as decimals:
80
+ # Public: Decode a VLQ string into mapping numbers.
81
+ #
82
+ # str - VLQ encoded String
110
83
  #
111
- # 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
112
- # 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
113
- def self.from_vlq_signed(vlq)
114
- if vlq & 1 == 1
115
- -(vlq >> 1)
116
- else
117
- vlq >> 1
84
+ # Returns an two dimensional Array of Integers.
85
+ def self.decode_mappings(str)
86
+ mappings = []
87
+
88
+ str.split(';').each_with_index do |group, index|
89
+ mappings[index] = []
90
+ group.split(',').each do |segment|
91
+ mappings[index] << decode(segment)
92
+ end
118
93
  end
119
- end
120
94
 
95
+ mappings
96
+ end
121
97
  end
122
98
  end
@@ -0,0 +1 @@
1
+ require 'source_map'
data/stdlib/strscan.rb CHANGED
@@ -10,6 +10,8 @@ class StringScanner
10
10
  @match = []
11
11
  end
12
12
 
13
+ attr_reader :string
14
+
13
15
  def bol?
14
16
  `#@pos === 0 || #@string.charAt(#@pos - 1) === "\n"`
15
17
  end
@@ -24,7 +26,7 @@ class StringScanner
24
26
  }
25
27
  else if (typeof(result) === 'object') {
26
28
  #@prev_pos = #@pos;
27
- #@pos += result[0].length;
29
+ #@pos += result[0].length;
28
30
  #@working = #@working.substring(result[0].length);
29
31
  #@matched = result[0];
30
32
  #@match = result;
@@ -55,6 +57,10 @@ class StringScanner
55
57
  return nil;
56
58
  }
57
59
 
60
+ if (match[idx] == null) {
61
+ return nil;
62
+ }
63
+
58
64
  return match[idx];
59
65
  }
60
66
  end
data/stdlib/template.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  class Template
2
2
  @_cache = {}
3
3
  def self.[](name)
4
- @_cache[name]
4
+ @_cache[name] || @_cache["templates/#{name}"]
5
5
  end
6
6
 
7
7
  def self.[]=(name, instance)
data/stdlib/thread.rb CHANGED
@@ -1,20 +1,160 @@
1
+ # This shim implementation of Thread is meant to only appease code that tries
2
+ # to be safe in the presence of threads, but does not actually utilize them,
3
+ # e.g., uses thread- or fiber-local variables.
4
+
5
+ class ThreadError < StandardError
6
+ end
7
+
1
8
  class Thread
2
9
  def self.current
3
- @current ||= self.new
10
+ unless @current
11
+ @current = allocate
12
+ @current.core_initialize!
13
+ end
14
+
15
+ @current
4
16
  end
5
17
 
6
- def initialize
7
- @vars = {}
18
+ def self.list
19
+ [current]
20
+ end
21
+
22
+ # Do not allow creation of new instances.
23
+ def initialize(*args)
24
+ fail NotImplementedError, "Thread creation not available"
8
25
  end
9
26
 
27
+ # fiber-local attribute access.
10
28
  def [](key)
11
- @vars[key]
29
+ @fiber_locals[coerce_key_name(key)]
30
+ end
31
+
32
+ def []=(key, value)
33
+ @fiber_locals[coerce_key_name(key)] = value
34
+ end
35
+
36
+ def key?(key)
37
+ @fiber_locals.key?(coerce_key_name(key))
38
+ end
39
+
40
+ def keys
41
+ @fiber_locals.keys
42
+ end
43
+
44
+ # thread-local attribute access.
45
+ def thread_variable_get(key)
46
+ @thread_locals[coerce_key_name(key)]
47
+ end
48
+
49
+ def thread_variable_set(key, value)
50
+ @thread_locals[coerce_key_name(key)] = value
51
+ end
52
+
53
+ def thread_variable?(key)
54
+ @thread_locals.key?(coerce_key_name(key))
55
+ end
56
+
57
+ def thread_variables
58
+ @thread_locals.keys
59
+ end
60
+
61
+ private
62
+ def core_initialize!
63
+ @thread_locals = {}
64
+ @fiber_locals = {}
65
+ end
66
+
67
+ def coerce_key_name(key)
68
+ Opal.coerce_to!(key, String, :to_s)
12
69
  end
13
70
 
14
- def []=(key, val)
15
- @vars[key] = val
71
+ public
72
+ class Queue
73
+ def initialize
74
+ clear
75
+ end
76
+
77
+ def clear
78
+ @storage = []
79
+ end
80
+
81
+ def empty?
82
+ @storage.empty?
83
+ end
84
+
85
+ def size
86
+ @storage.size
87
+ end
88
+
89
+ alias length size
90
+
91
+ def pop(non_block = false)
92
+ if empty?
93
+ fail ThreadError, "Queue empty" if non_block
94
+ fail ThreadError, "Deadlock"
95
+ end
96
+
97
+ @storage.shift
98
+ end
99
+
100
+ alias shift pop
101
+ alias deq pop
102
+
103
+ def push(value)
104
+ @storage.push(value)
105
+ end
106
+
107
+ alias << push
108
+ alias enq push
16
109
  end
110
+
17
111
  end
18
112
 
19
- class Queue
113
+ Queue = Thread::Queue
114
+
115
+ class Mutex
116
+ def initialize
117
+ # We still keep the @locked state so any logic based on try_lock while
118
+ # held yields reasonable results.
119
+ @locked = false
120
+ end
121
+
122
+ def lock
123
+ fail ThreadError, "Deadlock" if @locked
124
+ @locked = true
125
+ self
126
+ end
127
+
128
+ def locked?
129
+ @locked
130
+ end
131
+
132
+ def owned?
133
+ # Being the only "thread", we implicitly own any locked mutex.
134
+ @locked
135
+ end
136
+
137
+ def try_lock
138
+ if locked?
139
+ false
140
+ else
141
+ lock
142
+ true
143
+ end
144
+ end
145
+
146
+ def unlock
147
+ fail ThreadError, "Mutex not locked" unless @locked
148
+ @locked = false
149
+ self
150
+ end
151
+
152
+ def synchronize
153
+ lock
154
+ begin
155
+ yield
156
+ ensure
157
+ unlock
158
+ end
159
+ end
20
160
  end