opal 0.8.1 → 0.9.0.beta1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.gitmodules +3 -3
- data/.jshintrc +17 -20
- data/.travis.yml +22 -11
- data/CHANGELOG.md +51 -1
- data/CODE_OF_CONDUCT.md +15 -0
- data/CONTRIBUTING.md +125 -9
- data/Gemfile +1 -1
- data/Guardfile +2 -2
- data/README.md +95 -29
- data/Rakefile +1 -1
- data/benchmark/benchmarks +103 -0
- data/benchmark/bm_array_flatten.rb +9 -0
- data/benchmark/bm_array_intersection_numbers.rb +7 -0
- data/benchmark/bm_array_intersection_objects.rb +7 -0
- data/benchmark/bm_array_intersection_strings.rb +7 -0
- data/benchmark/bm_array_join_ary.rb +9 -0
- data/benchmark/bm_array_minus_numbers.rb +7 -0
- data/benchmark/bm_array_minus_objects.rb +7 -0
- data/benchmark/bm_array_minus_strings.rb +7 -0
- data/benchmark/bm_array_union_numbers.rb +7 -0
- data/benchmark/bm_array_union_objects.rb +7 -0
- data/benchmark/bm_array_union_strings.rb +7 -0
- data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
- data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
- data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
- data/benchmark/bm_array_uniq_numbers.rb +5 -0
- data/benchmark/bm_array_uniq_objects.rb +5 -0
- data/benchmark/bm_array_uniq_strings.rb +5 -0
- data/benchmark/bm_dispatch_bind_table.rb +57 -0
- data/benchmark/bm_dispatch_code_gen.rb +65 -0
- data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
- data/benchmark/bm_dispatch_hardcoded.rb +44 -0
- data/benchmark/bm_dispatch_send.rb +38 -0
- data/benchmark/bm_dispatch_send_table.rb +57 -0
- data/benchmark/bm_hash_assoc_object.rb +11 -0
- data/benchmark/bm_hash_assoc_string.rb +9 -0
- data/benchmark/bm_hash_clone_object.rb +9 -0
- data/benchmark/bm_hash_clone_string.rb +9 -0
- data/benchmark/bm_hash_delete_object.rb +11 -0
- data/benchmark/bm_hash_delete_string.rb +9 -0
- data/benchmark/bm_hash_each_key_object.rb +9 -0
- data/benchmark/bm_hash_each_key_string.rb +9 -0
- data/benchmark/bm_hash_each_object.rb +9 -0
- data/benchmark/bm_hash_each_string.rb +9 -0
- data/benchmark/bm_hash_each_value_object.rb +9 -0
- data/benchmark/bm_hash_each_value_string.rb +9 -0
- data/benchmark/bm_hash_element_reference_object.rb +11 -0
- data/benchmark/bm_hash_element_reference_string.rb +9 -0
- data/benchmark/bm_hash_element_set_object.rb +5 -0
- data/benchmark/bm_hash_element_set_string.rb +5 -0
- data/benchmark/bm_hash_equal_value_object.rb +14 -0
- data/benchmark/bm_hash_equal_value_string.rb +11 -0
- data/benchmark/bm_hash_fetch_object.rb +11 -0
- data/benchmark/bm_hash_fetch_string.rb +9 -0
- data/benchmark/bm_hash_flatten_object.rb +9 -0
- data/benchmark/bm_hash_flatten_string.rb +9 -0
- data/benchmark/bm_hash_has_key_object.rb +11 -0
- data/benchmark/bm_hash_has_key_string.rb +9 -0
- data/benchmark/bm_hash_has_value_object.rb +9 -0
- data/benchmark/bm_hash_has_value_string.rb +9 -0
- data/benchmark/bm_hash_hash_object.rb +9 -0
- data/benchmark/bm_hash_hash_string.rb +9 -0
- data/benchmark/bm_hash_inspect_object.rb +9 -0
- data/benchmark/bm_hash_inspect_string.rb +9 -0
- data/benchmark/bm_hash_invert_object.rb +9 -0
- data/benchmark/bm_hash_invert_string.rb +9 -0
- data/benchmark/bm_hash_keep_if_object.rb +9 -0
- data/benchmark/bm_hash_keep_if_string.rb +9 -0
- data/benchmark/bm_hash_key_object.rb +9 -0
- data/benchmark/bm_hash_key_string.rb +9 -0
- data/benchmark/bm_hash_keys_object.rb +9 -0
- data/benchmark/bm_hash_keys_string.rb +9 -0
- data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
- data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
- data/benchmark/bm_hash_literal_object_large.rb +4 -0
- data/benchmark/bm_hash_literal_object_small.rb +3 -0
- data/benchmark/bm_hash_literal_string_large.rb +4 -0
- data/benchmark/bm_hash_literal_string_small.rb +3 -0
- data/benchmark/bm_hash_merge_object.rb +22 -0
- data/benchmark/bm_hash_merge_string.rb +18 -0
- data/benchmark/bm_hash_rassoc_object.rb +9 -0
- data/benchmark/bm_hash_rassoc_string.rb +9 -0
- data/benchmark/bm_hash_rehash_object.rb +9 -0
- data/benchmark/bm_hash_rehash_string.rb +9 -0
- data/benchmark/bm_hash_reject_bang_object.rb +9 -0
- data/benchmark/bm_hash_reject_bang_string.rb +9 -0
- data/benchmark/bm_hash_reject_object.rb +9 -0
- data/benchmark/bm_hash_reject_string.rb +9 -0
- data/benchmark/bm_hash_replace_object.rb +18 -0
- data/benchmark/bm_hash_replace_string.rb +14 -0
- data/benchmark/bm_hash_select_bang_object.rb +9 -0
- data/benchmark/bm_hash_select_bang_string.rb +9 -0
- data/benchmark/bm_hash_select_object.rb +9 -0
- data/benchmark/bm_hash_select_string.rb +9 -0
- data/benchmark/bm_hash_shift_object.rb +10 -0
- data/benchmark/bm_hash_shift_string.rb +10 -0
- data/benchmark/bm_hash_to_a_object.rb +9 -0
- data/benchmark/bm_hash_to_a_string.rb +9 -0
- data/benchmark/bm_hash_to_h_object.rb +10 -0
- data/benchmark/bm_hash_to_h_string.rb +10 -0
- data/benchmark/bm_hash_values_object.rb +9 -0
- data/benchmark/bm_hash_values_string.rb +9 -0
- data/benchmark/run.rb +48 -0
- data/bin/opal-mspec +1 -1
- data/bin/opal-repl +4 -4
- data/docs/compiled_ruby.md +214 -56
- data/docs/configuring_gems.md +2 -2
- data/docs/faq.md +2 -2
- data/docs/getting_started.md +19 -2
- data/docs/jquery.md +5 -5
- data/docs/opal_parser.md +53 -0
- data/docs/unsupported_features.md +2 -2
- data/docs/upgrading.md +22 -0
- data/docs/using_sprockets.md +15 -0
- data/examples/rack/config.ru +13 -0
- data/examples/sinatra/config.ru +4 -5
- data/lib/mspec/opal/runner.rb +54 -11
- data/lib/opal.rb +1 -1
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/builder_processors.rb +1 -1
- data/lib/opal/cli.rb +17 -13
- data/lib/opal/cli_options.rb +1 -1
- data/lib/opal/compiler.rb +12 -0
- data/lib/opal/config.rb +4 -0
- data/lib/opal/nodes/arglist.rb +5 -7
- data/lib/opal/nodes/call.rb +6 -1
- data/lib/opal/nodes/call_special.rb +74 -0
- data/lib/opal/nodes/def.rb +35 -28
- data/lib/opal/nodes/definitions.rb +3 -5
- data/lib/opal/nodes/for.rb +13 -0
- data/lib/opal/nodes/helpers.rb +15 -1
- data/lib/opal/nodes/if.rb +5 -5
- data/lib/opal/nodes/iter.rb +6 -1
- data/lib/opal/nodes/literal.rb +1 -1
- data/lib/opal/nodes/logic.rb +2 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/module.rb +2 -1
- data/lib/opal/nodes/rescue.rb +10 -1
- data/lib/opal/nodes/scope.rb +8 -2
- data/lib/opal/nodes/singleton_class.rb +1 -1
- data/lib/opal/nodes/top.rb +11 -0
- data/lib/opal/nodes/variables.rb +4 -4
- data/lib/opal/parser.rb +21 -3
- data/lib/opal/parser/grammar.rb +3115 -2961
- data/lib/opal/parser/grammar.y +29 -6
- data/lib/opal/parser/lexer.rb +18 -8
- data/lib/opal/sprockets.rb +85 -0
- data/lib/opal/sprockets/processor.rb +11 -35
- data/lib/opal/sprockets/server.rb +3 -15
- data/lib/opal/version.rb +2 -2
- data/opal.gemspec +4 -4
- data/opal/README.md +9 -0
- data/opal/corelib/array.rb +433 -181
- data/opal/corelib/basic_object.rb +48 -4
- data/opal/corelib/boolean.rb +15 -6
- data/opal/corelib/class.rb +6 -5
- data/opal/corelib/comparable.rb +12 -0
- data/opal/corelib/complex.rb +282 -0
- data/opal/corelib/constants.rb +9 -0
- data/opal/corelib/enumerable.rb +83 -34
- data/opal/corelib/enumerator.rb +3 -1
- data/opal/corelib/error.rb +49 -10
- data/opal/corelib/file.rb +1 -0
- data/opal/corelib/hash.rb +353 -577
- data/opal/corelib/helpers.rb +20 -0
- data/opal/corelib/kernel.rb +114 -59
- data/opal/corelib/math.rb +470 -0
- data/opal/corelib/method.rb +11 -2
- data/opal/corelib/module.rb +96 -96
- data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
- data/opal/corelib/number.rb +751 -0
- data/opal/corelib/numeric.rb +77 -437
- data/opal/corelib/proc.rb +81 -1
- data/opal/corelib/process.rb +27 -0
- data/opal/corelib/rational.rb +358 -0
- data/opal/corelib/regexp.rb +156 -27
- data/opal/corelib/runtime.js +724 -335
- data/opal/corelib/string.rb +93 -104
- data/opal/corelib/string/encoding.rb +177 -0
- data/opal/corelib/string/inheritance.rb +2 -0
- data/opal/corelib/struct.rb +105 -18
- data/opal/corelib/time.rb +267 -146
- data/opal/corelib/unsupported.rb +216 -0
- data/opal/corelib/variables.rb +0 -6
- data/opal/opal.rb +8 -22
- data/opal/opal/base.rb +9 -0
- data/opal/opal/mini.rb +17 -0
- data/spec/README.md +1 -1
- data/spec/filters/bugs/array.rb +38 -136
- data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
- data/spec/filters/bugs/class.rb +6 -12
- data/spec/filters/bugs/complex.rb +3 -0
- data/spec/filters/bugs/date.rb +162 -10
- data/spec/filters/bugs/enumerable.rb +31 -58
- data/spec/filters/bugs/enumerator.rb +42 -0
- data/spec/filters/bugs/exception.rb +66 -10
- data/spec/filters/bugs/float.rb +17 -0
- data/spec/filters/bugs/hash.rb +11 -97
- data/spec/filters/bugs/inheritance.rb +5 -0
- data/spec/filters/bugs/integer.rb +28 -0
- data/spec/filters/bugs/kernel.rb +304 -12
- data/spec/filters/bugs/language.rb +133 -399
- data/spec/filters/bugs/language_opal.rb +88 -0
- data/spec/filters/bugs/module.rb +203 -62
- data/spec/filters/bugs/numeric.rb +32 -0
- data/spec/filters/bugs/proc.rb +39 -0
- data/spec/filters/bugs/range.rb +148 -0
- data/spec/filters/bugs/regexp.rb +168 -0
- data/spec/filters/bugs/set.rb +46 -3
- data/spec/filters/bugs/singleton.rb +1 -2
- data/spec/filters/bugs/string.rb +59 -90
- data/spec/filters/bugs/strscan.rb +80 -0
- data/spec/filters/bugs/struct.rb +10 -20
- data/spec/filters/bugs/time.rb +17 -184
- data/spec/filters/bugs/unboundmethod.rb +22 -0
- data/spec/filters/unsupported/array.rb +163 -0
- data/spec/filters/unsupported/basicobject.rb +14 -0
- data/spec/filters/unsupported/bignum.rb +46 -0
- data/spec/filters/unsupported/class.rb +4 -0
- data/spec/filters/unsupported/delegator.rb +5 -0
- data/spec/filters/unsupported/enumerable.rb +11 -0
- data/spec/filters/unsupported/enumerator.rb +8 -9
- data/spec/filters/unsupported/fixnum.rb +14 -0
- data/spec/filters/unsupported/float.rb +41 -7
- data/spec/filters/unsupported/freeze.rb +45 -0
- data/spec/filters/unsupported/hash.rb +50 -0
- data/spec/filters/unsupported/integer.rb +3 -0
- data/spec/filters/unsupported/kernel.rb +31 -0
- data/spec/filters/unsupported/language.rb +17 -0
- data/spec/filters/unsupported/matchdata.rb +30 -0
- data/spec/filters/unsupported/math.rb +3 -0
- data/spec/filters/unsupported/module.rb +5 -3
- data/spec/filters/unsupported/pathname.rb +3 -0
- data/spec/filters/unsupported/privacy.rb +136 -0
- data/spec/filters/unsupported/proc.rb +3 -0
- data/spec/filters/unsupported/regexp.rb +59 -0
- data/spec/filters/unsupported/set.rb +4 -0
- data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
- data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +5 -0
- data/spec/filters/unsupported/taint.rb +16 -0
- data/spec/filters/unsupported/thread.rb +5 -0
- data/spec/filters/unsupported/time.rb +197 -16
- data/spec/lib/cli_spec.rb +14 -4
- data/spec/lib/compiler_spec.rb +9 -1
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/not_spec.rb +2 -8
- data/spec/lib/sprockets_spec.rb +24 -0
- data/spec/opal/core/array/intersection_spec.rb +38 -0
- data/spec/opal/core/array/minus_spec.rb +38 -0
- data/spec/opal/core/array/union_spec.rb +38 -0
- data/spec/opal/core/array/uniq_spec.rb +49 -0
- data/spec/opal/core/exception_spec.rb +7 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
- data/spec/opal/core/hash/internals_spec.rb +332 -0
- data/spec/opal/core/helpers_spec.rb +14 -0
- data/spec/opal/core/kernel/freeze_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +13 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
- data/spec/opal/core/language/class_spec.rb +55 -0
- data/spec/opal/core/language/fixtures/send.rb +1 -0
- data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
- data/spec/opal/core/language/send_spec.rb +5 -0
- data/spec/opal/core/method/to_proc_spec.rb +28 -0
- data/spec/opal/core/module/name_spec.rb +0 -17
- data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
- data/spec/opal/core/runtime/eval_spec.rb +1 -1
- data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
- data/spec/opal/core/runtime_spec.rb +51 -0
- data/spec/opal/stdlib/js_spec.rb +66 -0
- data/spec/opal/stdlib/native/hash_spec.rb +36 -0
- data/spec/rubyspecs +152 -273
- data/spec/spec_helper.rb +10 -11
- data/stdlib/base64.rb +9 -9
- data/stdlib/benchmark.rb +551 -4
- data/stdlib/console.rb +94 -0
- data/stdlib/date.rb +1 -1
- data/stdlib/encoding.rb +1 -170
- data/stdlib/js.rb +56 -0
- data/stdlib/json.rb +9 -14
- data/stdlib/math.rb +1 -370
- data/stdlib/native.rb +133 -63
- data/stdlib/nodejs/file.rb +5 -0
- data/stdlib/nodejs/fileutils.rb +13 -6
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
- data/stdlib/opal-parser.rb +1 -2
- data/stdlib/ostruct.rb +65 -6
- data/stdlib/pp.rb +2 -4
- data/stdlib/rbconfig.rb +1 -3
- data/stdlib/strscan.rb +164 -28
- data/tasks/benchmarking.rake +88 -0
- data/tasks/testing.rake +181 -55
- data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
- data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
- data/test/opal/test_keyword.rb +590 -0
- data/vendored-minitest/minitest.rb +2 -2
- data/vendored-minitest/test/unit.rb +5 -0
- metadata +229 -62
- data/benchmarks/operators.rb +0 -11
- data/benchmarks/prova.js.rb +0 -13
- data/docs/libraries.md +0 -36
- data/lib/mspec/opal/new.html.erb +0 -1
- data/lib/mspec/opal/rake_task.rb +0 -248
- data/opal/corelib/match_data.rb +0 -128
- data/spec/filters/bugs/math.rb +0 -95
- data/spec/filters/bugs/nil.rb +0 -7
- data/spec/filters/bugs/opal.rb +0 -9
- data/spec/filters/bugs/regular_expressions.rb +0 -41
- data/spec/filters/bugs/stringscanner.rb +0 -33
- data/spec/filters/unsupported/encoding.rb +0 -102
- data/spec/filters/unsupported/frozen.rb +0 -92
- data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
- data/spec/filters/unsupported/integer_size.rb +0 -59
- data/spec/filters/unsupported/method_added.rb +0 -10
- data/spec/filters/unsupported/private_constants.rb +0 -30
- data/spec/filters/unsupported/private_methods.rb +0 -55
- data/spec/filters/unsupported/random.rb +0 -4
- data/spec/filters/unsupported/rational_numbers.rb +0 -4
- data/spec/filters/unsupported/regular_expressions.rb +0 -137
- data/spec/filters/unsupported/ruby_exe.rb +0 -5
- data/spec/filters/unsupported/symbols.rb +0 -17
- data/spec/filters/unsupported/tainted.rb +0 -180
- data/spec/filters/unsupported/trusted.rb +0 -88
- data/stdlib/process.rb +0 -10
- data/tasks/documenting.rake +0 -37
data/opal/corelib/regexp.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class RegexpError < StandardError; end
|
2
|
-
|
2
|
+
|
3
|
+
class Regexp < `RegExp`
|
3
4
|
IGNORECASE = 1
|
4
5
|
MULTILINE = 4
|
5
6
|
|
@@ -67,35 +68,30 @@ class Regexp
|
|
67
68
|
|
68
69
|
def new(regexp, options = undefined)
|
69
70
|
%x{
|
70
|
-
|
71
|
-
|
71
|
+
if (regexp.$$is_regexp) {
|
72
|
+
return new RegExp(regexp);
|
73
|
+
}
|
74
|
+
|
75
|
+
regexp = #{Opal.coerce_to!(regexp, String, :to_str)};
|
76
|
+
|
77
|
+
if (regexp.charAt(regexp.length - 1) === '\\') {
|
72
78
|
#{raise RegexpError, "too short escape sequence: /#{regexp}/"}
|
73
79
|
}
|
74
|
-
|
75
|
-
if (options
|
76
|
-
|
80
|
+
|
81
|
+
if (options === undefined || #{!options}) {
|
82
|
+
return new RegExp(regexp);
|
77
83
|
}
|
78
|
-
|
79
|
-
if (options
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
if (#{MULTILINE} & options) {
|
90
|
-
result += 'm';
|
91
|
-
}
|
92
|
-
options = result;
|
93
|
-
}
|
94
|
-
else {
|
95
|
-
options = 'i';
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
84
|
+
|
85
|
+
if (options.$$is_number) {
|
86
|
+
var temp = '';
|
87
|
+
if (#{IGNORECASE} & options) { temp += 'i'; }
|
88
|
+
if (#{MULTILINE} & options) { temp += 'm'; }
|
89
|
+
options = temp;
|
90
|
+
}
|
91
|
+
else {
|
92
|
+
options = 'i';
|
93
|
+
}
|
94
|
+
|
99
95
|
return new RegExp(regexp, options);
|
100
96
|
}
|
101
97
|
end
|
@@ -199,6 +195,139 @@ class Regexp
|
|
199
195
|
return result;
|
200
196
|
}
|
201
197
|
end
|
198
|
+
|
199
|
+
def casefold?
|
200
|
+
`self.ignoreCase`
|
201
|
+
end
|
202
202
|
|
203
203
|
alias to_s source
|
204
204
|
end
|
205
|
+
|
206
|
+
class MatchData
|
207
|
+
attr_reader :post_match, :pre_match, :regexp, :string
|
208
|
+
|
209
|
+
def initialize(regexp, match_groups)
|
210
|
+
$~ = self
|
211
|
+
@regexp = regexp
|
212
|
+
@begin = `match_groups.index`
|
213
|
+
@string = `match_groups.input`
|
214
|
+
@pre_match = `match_groups.input.slice(0, match_groups.index)`
|
215
|
+
@post_match = `match_groups.input.slice(match_groups.index + match_groups[0].length)`
|
216
|
+
@matches = []
|
217
|
+
|
218
|
+
%x{
|
219
|
+
for (var i = 0, length = match_groups.length; i < length; i++) {
|
220
|
+
var group = match_groups[i];
|
221
|
+
|
222
|
+
if (group == null) {
|
223
|
+
#@matches.push(nil);
|
224
|
+
}
|
225
|
+
else {
|
226
|
+
#@matches.push(group);
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
end
|
231
|
+
|
232
|
+
def [](*args)
|
233
|
+
@matches[*args]
|
234
|
+
end
|
235
|
+
|
236
|
+
def offset(n)
|
237
|
+
%x{
|
238
|
+
if (n !== 0) {
|
239
|
+
#{raise ArgumentError, 'MatchData#offset only supports 0th element'}
|
240
|
+
}
|
241
|
+
return [self.begin, self.begin + self.matches[n].length];
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
def ==(other)
|
246
|
+
return false unless MatchData === other
|
247
|
+
|
248
|
+
`self.string == other.string` &&
|
249
|
+
`self.regexp.toString() == other.regexp.toString()` &&
|
250
|
+
`self.pre_match == other.pre_match` &&
|
251
|
+
`self.post_match == other.post_match` &&
|
252
|
+
`self.begin == other.begin`
|
253
|
+
end
|
254
|
+
|
255
|
+
alias eql? ==
|
256
|
+
|
257
|
+
def begin(n)
|
258
|
+
%x{
|
259
|
+
if (n !== 0) {
|
260
|
+
#{raise ArgumentError, 'MatchData#begin only supports 0th element'}
|
261
|
+
}
|
262
|
+
return self.begin;
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
def end(n)
|
267
|
+
%x{
|
268
|
+
if (n !== 0) {
|
269
|
+
#{raise ArgumentError, 'MatchData#end only supports 0th element'}
|
270
|
+
}
|
271
|
+
return self.begin + self.matches[n].length;
|
272
|
+
}
|
273
|
+
end
|
274
|
+
|
275
|
+
def captures
|
276
|
+
`#@matches.slice(1)`
|
277
|
+
end
|
278
|
+
|
279
|
+
def inspect
|
280
|
+
%x{
|
281
|
+
var str = "#<MatchData " + #{`#@matches[0]`.inspect};
|
282
|
+
|
283
|
+
for (var i = 1, length = #@matches.length; i < length; i++) {
|
284
|
+
str += " " + i + ":" + #{`#@matches[i]`.inspect};
|
285
|
+
}
|
286
|
+
|
287
|
+
return str + ">";
|
288
|
+
}
|
289
|
+
end
|
290
|
+
|
291
|
+
def length
|
292
|
+
`#@matches.length`
|
293
|
+
end
|
294
|
+
|
295
|
+
alias size length
|
296
|
+
|
297
|
+
def to_a
|
298
|
+
@matches
|
299
|
+
end
|
300
|
+
|
301
|
+
def to_s
|
302
|
+
`#@matches[0]`
|
303
|
+
end
|
304
|
+
|
305
|
+
def values_at(*args)
|
306
|
+
%x{
|
307
|
+
var i, a, index, values = [];
|
308
|
+
|
309
|
+
for (i = 0; i < args.length; i++) {
|
310
|
+
|
311
|
+
if (args[i].$$is_range) {
|
312
|
+
a = #{`args[i]`.to_a};
|
313
|
+
a.unshift(i, 1);
|
314
|
+
Array.prototype.splice.apply(args, a);
|
315
|
+
}
|
316
|
+
|
317
|
+
index = #{Opal.coerce_to!(`args[i]`, Integer, :to_int)};
|
318
|
+
|
319
|
+
if (index < 0) {
|
320
|
+
index += #@matches.length;
|
321
|
+
if (index < 0) {
|
322
|
+
values.push(nil);
|
323
|
+
continue;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
values.push(#@matches[index]);
|
328
|
+
}
|
329
|
+
|
330
|
+
return values;
|
331
|
+
}
|
332
|
+
end
|
333
|
+
end
|
data/opal/corelib/runtime.js
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
var Opal = this.Opal = {};
|
9
9
|
|
10
10
|
// All bridged classes - keep track to donate methods from Object
|
11
|
-
var
|
11
|
+
var bridges = {};
|
12
12
|
|
13
13
|
// TopScope is used for inheriting constants from the top scope
|
14
14
|
var TopScope = function(){};
|
@@ -51,6 +51,9 @@
|
|
51
51
|
// Exit function, this should be replaced by platform specific implementation
|
52
52
|
// (See nodejs and phantom for examples)
|
53
53
|
Opal.exit = function(status) { if (Opal.gvars.DEBUG) console.log('Exited with status '+status); };
|
54
|
+
|
55
|
+
// keeps track of exceptions for $!
|
56
|
+
Opal.exceptions = [];
|
54
57
|
|
55
58
|
/**
|
56
59
|
Get a constant on the given scope. Every class and module in Opal has a
|
@@ -72,7 +75,7 @@
|
|
72
75
|
var constant = this[name];
|
73
76
|
|
74
77
|
if (constant == null) {
|
75
|
-
return this.base.$
|
78
|
+
return this.base.$const_get(name);
|
76
79
|
}
|
77
80
|
|
78
81
|
return constant;
|
@@ -95,9 +98,7 @@
|
|
95
98
|
const_scope.constants = [];
|
96
99
|
|
97
100
|
if (id) {
|
98
|
-
|
99
|
-
base[id] = base.constructor[id] = klass;
|
100
|
-
base.constants.push(id);
|
101
|
+
Opal.cdecl(base, id, klass)
|
101
102
|
}
|
102
103
|
}
|
103
104
|
|
@@ -130,46 +131,54 @@
|
|
130
131
|
*/
|
131
132
|
Opal.klass = function(base, superklass, id, constructor) {
|
132
133
|
// If base is an object, use its class
|
133
|
-
if (!base.$$is_class) {
|
134
|
+
if (!base.$$is_class && !base.$$is_module) {
|
134
135
|
base = base.$$class;
|
135
136
|
}
|
136
137
|
|
137
|
-
|
138
|
-
|
139
|
-
superklass = ObjectClass;
|
140
|
-
}
|
141
|
-
|
142
|
-
var klass = base.$$scope[id];
|
138
|
+
var klass = base.$$scope[id],
|
139
|
+
bridged = typeof(superklass) === 'function';
|
143
140
|
|
144
|
-
// If
|
145
|
-
if (
|
141
|
+
// If the class exists in the scope, then we must use that
|
142
|
+
if (klass && klass.$$orig_scope === base.$$scope) {
|
146
143
|
// Make sure the existing constant is a class, or raise error
|
147
144
|
if (!klass.$$is_class) {
|
148
145
|
throw Opal.TypeError.$new(id + " is not a class");
|
149
146
|
}
|
150
147
|
|
151
148
|
// Make sure existing class has same superclass
|
152
|
-
if (superklass
|
149
|
+
if (superklass && klass.$$super !== superklass) {
|
153
150
|
throw Opal.TypeError.$new("superclass mismatch for class " + id);
|
154
151
|
}
|
152
|
+
|
153
|
+
return klass;
|
155
154
|
}
|
156
|
-
|
157
|
-
|
158
|
-
|
155
|
+
|
156
|
+
// Not specifying a superclass means we can assume it to be Object
|
157
|
+
if (superklass === null) {
|
158
|
+
superklass = ObjectClass;
|
159
159
|
}
|
160
|
-
else {
|
161
|
-
// if class doesnt exist, create a new one with given superclass
|
162
|
-
klass = boot_class(superklass, constructor);
|
163
160
|
|
164
|
-
|
165
|
-
|
161
|
+
// if class doesnt exist, create a new one with given superclass
|
162
|
+
klass = bridged ?
|
163
|
+
boot_class_object(ObjectClass, superklass) :
|
164
|
+
boot_class(superklass, constructor);
|
165
|
+
|
166
|
+
// name class using base (e.g. Foo or Foo::Baz)
|
167
|
+
klass.$$name = id;
|
166
168
|
|
167
|
-
|
168
|
-
|
169
|
+
// mark the object as a class
|
170
|
+
klass.$$is_class = true;
|
169
171
|
|
170
|
-
|
171
|
-
|
172
|
+
// every class gets its own constant scope, inherited from current scope
|
173
|
+
create_scope(base.$$scope, klass, id);
|
172
174
|
|
175
|
+
// Name new class directly onto current scope (Opal.Foo.Baz = klass)
|
176
|
+
base[id] = base.$$scope[id] = klass;
|
177
|
+
|
178
|
+
if (bridged) {
|
179
|
+
Opal.bridge(klass, superklass);
|
180
|
+
}
|
181
|
+
else {
|
173
182
|
// Copy all parent constants to child, unless parent is Object
|
174
183
|
if (superklass !== ObjectClass && superklass !== BasicObjectClass) {
|
175
184
|
donate_constants(superklass, klass);
|
@@ -256,8 +265,16 @@
|
|
256
265
|
// Maybe there are some browsers not abiding (IE6?)
|
257
266
|
module.constructor = constructor;
|
258
267
|
|
259
|
-
|
260
|
-
|
268
|
+
if (superklass === ModuleClass) {
|
269
|
+
// @property $$is_module Clearly mark this as a module
|
270
|
+
module.$$is_module = true;
|
271
|
+
module.$$class = ModuleClass;
|
272
|
+
}
|
273
|
+
else {
|
274
|
+
// @property $$is_class Clearly mark this as a class
|
275
|
+
module.$$is_class = true;
|
276
|
+
module.$$class = ClassClass;
|
277
|
+
}
|
261
278
|
|
262
279
|
// @property $$super the superclass, doesn't get changed by module inclusions
|
263
280
|
module.$$super = superklass;
|
@@ -267,12 +284,6 @@
|
|
267
284
|
// the last included module
|
268
285
|
module.$$parent = superklass;
|
269
286
|
|
270
|
-
// @property $$methods keeps track of methods defined on the class
|
271
|
-
// but seems to be used just by `define_basic_object_method`
|
272
|
-
// and for donating (Ruby) Object methods to bridged classes
|
273
|
-
// TODO: check if it can be removed
|
274
|
-
module.$$methods = [];
|
275
|
-
|
276
287
|
// @property $$inc included modules
|
277
288
|
module.$$inc = [];
|
278
289
|
}
|
@@ -300,21 +311,29 @@
|
|
300
311
|
Opal.module = function(base, id) {
|
301
312
|
var module;
|
302
313
|
|
303
|
-
if (!base.$$is_class) {
|
314
|
+
if (!base.$$is_class && !base.$$is_module) {
|
304
315
|
base = base.$$class;
|
305
316
|
}
|
306
317
|
|
307
318
|
if ($hasOwn.call(base.$$scope, id)) {
|
308
319
|
module = base.$$scope[id];
|
309
320
|
|
310
|
-
if (!module.$$
|
321
|
+
if (!module.$$is_module && module !== ObjectClass) {
|
311
322
|
throw Opal.TypeError.$new(id + " is not a module");
|
312
323
|
}
|
313
324
|
}
|
314
325
|
else {
|
315
326
|
module = boot_module_object();
|
327
|
+
|
328
|
+
// name module using base (e.g. Foo or Foo::Baz)
|
316
329
|
module.$$name = id;
|
317
330
|
|
331
|
+
// mark the object as a module
|
332
|
+
module.$$is_module = true;
|
333
|
+
|
334
|
+
// initialize dependency tracking
|
335
|
+
module.$$dep = [];
|
336
|
+
|
318
337
|
create_scope(base.$$scope, module, id);
|
319
338
|
|
320
339
|
// Name new module directly onto current scope (Opal.Foo.Baz = module)
|
@@ -340,9 +359,6 @@
|
|
340
359
|
|
341
360
|
setup_module_or_class_object(module, module_constructor, ModuleClass, module_prototype);
|
342
361
|
|
343
|
-
module.$$is_mod = true;
|
344
|
-
module.$$dep = [];
|
345
|
-
|
346
362
|
return module;
|
347
363
|
}
|
348
364
|
|
@@ -364,7 +380,7 @@
|
|
364
380
|
return object.$$meta;
|
365
381
|
}
|
366
382
|
|
367
|
-
if (object.$$is_class) {
|
383
|
+
if (object.$$is_class || object.$$is_module) {
|
368
384
|
return build_class_singleton_class(object);
|
369
385
|
}
|
370
386
|
|
@@ -381,14 +397,14 @@
|
|
381
397
|
@returns [RubyClass]
|
382
398
|
*/
|
383
399
|
function build_class_singleton_class(klass) {
|
384
|
-
var meta = new Opal.Class.$$alloc;
|
400
|
+
var meta = new Opal.Class.$$alloc();
|
385
401
|
|
386
402
|
meta.$$class = Opal.Class;
|
387
403
|
meta.$$proto = klass.constructor.prototype;
|
388
404
|
|
389
405
|
meta.$$is_singleton = true;
|
406
|
+
meta.$$singleton_of = klass;
|
390
407
|
meta.$$inc = [];
|
391
|
-
meta.$$methods = [];
|
392
408
|
meta.$$scope = klass.$$scope;
|
393
409
|
|
394
410
|
return klass.$$meta = meta;
|
@@ -412,9 +428,95 @@
|
|
412
428
|
meta.$$class = orig_class.$$class;
|
413
429
|
meta.$$scope = orig_class.$$scope;
|
414
430
|
meta.$$parent = orig_class;
|
431
|
+
meta.$$is_singleton = true;
|
432
|
+
meta.$$singleton_of = object;
|
433
|
+
|
415
434
|
return object.$$meta = meta;
|
416
435
|
}
|
417
436
|
|
437
|
+
/**
|
438
|
+
The actual inclusion of a module into a class.
|
439
|
+
|
440
|
+
## Class `$$parent` and `iclass`
|
441
|
+
|
442
|
+
To handle `super` calls, every class has a `$$parent`. This parent is
|
443
|
+
used to resolve the next class for a super call. A normal class would
|
444
|
+
have this point to its superclass. However, if a class includes a module
|
445
|
+
then this would need to take into account the module. The module would
|
446
|
+
also have to then point its `$$parent` to the actual superclass. We
|
447
|
+
cannot modify modules like this, because it might be included in more
|
448
|
+
then one class. To fix this, we actually insert an `iclass` as the class'
|
449
|
+
`$$parent` which can then point to the superclass. The `iclass` acts as
|
450
|
+
a proxy to the actual module, so the `super` chain can then search it for
|
451
|
+
the required method.
|
452
|
+
|
453
|
+
@param [RubyModule] module the module to include
|
454
|
+
@param [RubyClass] klass the target class to include module into
|
455
|
+
@returns [null]
|
456
|
+
*/
|
457
|
+
function bridge() {
|
458
|
+
var target, donator, from, name, body, ancestors, id, methods, method, i, ancestor, bridged, length;
|
459
|
+
|
460
|
+
if (arguments.length === 4) {
|
461
|
+
target = arguments[0];
|
462
|
+
from = arguments[1];
|
463
|
+
name = arguments[2];
|
464
|
+
body = arguments[3];
|
465
|
+
ancestors = target.$$bridge.$ancestors();
|
466
|
+
|
467
|
+
// order important here, we have to check for method presence in
|
468
|
+
// ancestors from the bridged class to the last ancestor
|
469
|
+
for (i = 0, length = ancestors.length; i < length; i++) {
|
470
|
+
ancestor = ancestors[i];
|
471
|
+
|
472
|
+
if ($hasOwn.call(ancestor.$$proto, name) &&
|
473
|
+
ancestor.$$proto[name] &&
|
474
|
+
!ancestor.$$proto[name].$$donated &&
|
475
|
+
!ancestor.$$proto[name].$$stub &&
|
476
|
+
ancestor !== from) {
|
477
|
+
break;
|
478
|
+
}
|
479
|
+
|
480
|
+
if (ancestor === from) {
|
481
|
+
target.prototype[name] = body
|
482
|
+
break;
|
483
|
+
}
|
484
|
+
}
|
485
|
+
}
|
486
|
+
else {
|
487
|
+
target = arguments[0];
|
488
|
+
donator = arguments[1];
|
489
|
+
|
490
|
+
if (typeof(target) === "function") {
|
491
|
+
id = donator.$__id__();
|
492
|
+
methods = donator.$instance_methods();
|
493
|
+
|
494
|
+
for (i = methods.length - 1; i >= 0; i--) {
|
495
|
+
method = '$' + methods[i];
|
496
|
+
|
497
|
+
bridge(target, donator, method, donator.$$proto[method]);
|
498
|
+
}
|
499
|
+
|
500
|
+
if (!bridges[id]) {
|
501
|
+
bridges[id] = [];
|
502
|
+
}
|
503
|
+
|
504
|
+
bridges[id].push(target);
|
505
|
+
}
|
506
|
+
else {
|
507
|
+
bridged = bridges[target.$__id__()];
|
508
|
+
|
509
|
+
if (bridged) {
|
510
|
+
for (i = bridged.length - 1; i >= 0; i--) {
|
511
|
+
bridge(bridged[i], donator);
|
512
|
+
}
|
513
|
+
|
514
|
+
bridges[donator.$__id__()] = bridged.slice();
|
515
|
+
}
|
516
|
+
}
|
517
|
+
}
|
518
|
+
}
|
519
|
+
|
418
520
|
/**
|
419
521
|
The actual inclusion of a module into a class.
|
420
522
|
|
@@ -436,20 +538,21 @@
|
|
436
538
|
@returns [null]
|
437
539
|
*/
|
438
540
|
Opal.append_features = function(module, klass) {
|
439
|
-
var
|
541
|
+
var iclass, donator, prototype, methods, id, i;
|
440
542
|
|
441
|
-
// check if this module is already included in the
|
442
|
-
for (
|
443
|
-
if (
|
543
|
+
// check if this module is already included in the class
|
544
|
+
for (i = klass.$$inc.length - 1; i >= 0; i--) {
|
545
|
+
if (klass.$$inc[i] === module) {
|
444
546
|
return;
|
445
547
|
}
|
446
548
|
}
|
447
549
|
|
448
|
-
|
550
|
+
klass.$$inc.push(module);
|
449
551
|
module.$$dep.push(klass);
|
552
|
+
bridge(klass, module);
|
450
553
|
|
451
554
|
// iclass
|
452
|
-
|
555
|
+
iclass = {
|
453
556
|
$$name: module.$$name,
|
454
557
|
$$proto: module.$$proto,
|
455
558
|
$$parent: klass.$$parent,
|
@@ -459,28 +562,24 @@
|
|
459
562
|
|
460
563
|
klass.$$parent = iclass;
|
461
564
|
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
for (var i = 0, length = methods.length; i < length; i++) {
|
467
|
-
var method = methods[i], current;
|
565
|
+
donator = module.$$proto;
|
566
|
+
prototype = klass.$$proto;
|
567
|
+
methods = module.$instance_methods();
|
468
568
|
|
569
|
+
for (i = methods.length - 1; i >= 0; i--) {
|
570
|
+
id = '$' + methods[i];
|
469
571
|
|
470
|
-
if
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
prototype[method] = donator[method];
|
478
|
-
prototype[method].$$donated = true;
|
572
|
+
// if the target class already has a method of the same name defined
|
573
|
+
// and that method was NOT donated, then it must be a method defined
|
574
|
+
// by the class so we do not want to override it
|
575
|
+
if ( prototype.hasOwnProperty(id) &&
|
576
|
+
!prototype[id].$$donated &&
|
577
|
+
!prototype[id].$$stub) {
|
578
|
+
continue;
|
479
579
|
}
|
480
|
-
}
|
481
580
|
|
482
|
-
|
483
|
-
|
581
|
+
prototype[id] = donator[id];
|
582
|
+
prototype[id].$$donated = module;
|
484
583
|
}
|
485
584
|
|
486
585
|
donate_constants(module, klass);
|
@@ -540,68 +639,80 @@
|
|
540
639
|
}
|
541
640
|
|
542
641
|
/*
|
543
|
-
* For performance, some core
|
544
|
-
* native
|
642
|
+
* For performance, some core Ruby classes are toll-free bridged to their
|
643
|
+
* native JavaScript counterparts (e.g. a Ruby Array is a JavaScript Array).
|
545
644
|
*
|
546
645
|
* This method is used to setup a native constructor (e.g. Array), to have
|
547
|
-
* its prototype act like a normal
|
646
|
+
* its prototype act like a normal Ruby class. Firstly, a new Ruby class is
|
548
647
|
* created using the native constructor so that its prototype is set as the
|
549
648
|
* target for th new class. Note: all bridged classes are set to inherit
|
550
649
|
* from Object.
|
551
650
|
*
|
552
|
-
* Bridged classes are tracked in `bridged_classes` array so that methods
|
553
|
-
* defined on Object can be "donated" to all bridged classes. This allows
|
554
|
-
* us to fake the inheritance of a native prototype from our Object
|
555
|
-
* prototype.
|
556
|
-
*
|
557
651
|
* Example:
|
558
652
|
*
|
559
|
-
*
|
653
|
+
* Opal.bridge(self, Function);
|
560
654
|
*
|
561
|
-
* @param [
|
562
|
-
* @param [Function] constructor native
|
563
|
-
* @
|
564
|
-
* @return [Class] returns new ruby class
|
655
|
+
* @param [Class] klass the Ruby class to bridge
|
656
|
+
* @param [Function] constructor native JavaScript constructor to use
|
657
|
+
* @return [Class] returns the passed Ruby class
|
565
658
|
*/
|
566
|
-
function
|
567
|
-
|
568
|
-
|
569
|
-
klass.$$name = name;
|
570
|
-
|
571
|
-
if (base === undefined) {
|
572
|
-
base = Opal;
|
573
|
-
}
|
574
|
-
else {
|
575
|
-
base = base.$$scope;
|
659
|
+
Opal.bridge = function(klass, constructor) {
|
660
|
+
if (constructor.$$bridge) {
|
661
|
+
throw Opal.ArgumentError.$new("already bridged");
|
576
662
|
}
|
577
663
|
|
578
|
-
|
579
|
-
|
664
|
+
Opal.stub_subscribers.push(constructor.prototype);
|
665
|
+
|
666
|
+
constructor.prototype.$$class = klass;
|
667
|
+
constructor.$$bridge = klass;
|
580
668
|
|
581
|
-
var
|
669
|
+
var ancestors = klass.$ancestors();
|
582
670
|
|
583
|
-
|
584
|
-
|
585
|
-
|
671
|
+
// order important here, we have to bridge from the last ancestor to the
|
672
|
+
// bridged class
|
673
|
+
for (var i = ancestors.length - 1; i >= 0; i--) {
|
674
|
+
bridge(constructor, ancestors[i]);
|
586
675
|
}
|
587
676
|
|
588
|
-
|
677
|
+
for (var name in BasicObject.prototype) {
|
678
|
+
var method = BasicObject.prototype[method];
|
679
|
+
|
680
|
+
if (method && method.$$stub && !(name in constructor.prototype)) {
|
681
|
+
constructor.prototype[name] = method;
|
682
|
+
}
|
683
|
+
}
|
589
684
|
|
590
685
|
return klass;
|
591
686
|
}
|
592
687
|
|
688
|
+
|
593
689
|
/*
|
594
690
|
* constant assign
|
595
691
|
*/
|
596
692
|
Opal.casgn = function(base_module, name, value) {
|
597
|
-
|
693
|
+
function update(klass, name) {
|
694
|
+
klass.$$name = name;
|
598
695
|
|
599
|
-
|
600
|
-
|
696
|
+
for (name in klass.$$scope) {
|
697
|
+
var value = klass.$$scope[name];
|
698
|
+
|
699
|
+
if (value.$$name === nil && (value.$$is_class || value.$$is_module)) {
|
700
|
+
update(value, name)
|
701
|
+
}
|
702
|
+
}
|
601
703
|
}
|
602
704
|
|
603
|
-
|
604
|
-
|
705
|
+
var scope = base_module.$$scope;
|
706
|
+
|
707
|
+
if (value.$$is_class || value.$$is_module) {
|
708
|
+
// only checking ObjectClass prevents setting a const on an anonymous class that has a superclass that's not Object
|
709
|
+
if (value.$$is_class || value.$$base_module === ObjectClass) {
|
710
|
+
value.$$base_module = base_module;
|
711
|
+
}
|
712
|
+
|
713
|
+
if (value.$$name === nil && value.$$base_module.$$name !== nil) {
|
714
|
+
update(value, name);
|
715
|
+
}
|
605
716
|
}
|
606
717
|
|
607
718
|
scope.constants.push(name);
|
@@ -612,6 +723,12 @@
|
|
612
723
|
* constant decl
|
613
724
|
*/
|
614
725
|
Opal.cdecl = function(base_scope, name, value) {
|
726
|
+
if ((value.$$is_class || value.$$is_module) && value.$$orig_scope == null) {
|
727
|
+
value.$$name = name;
|
728
|
+
value.$$orig_scope = base_scope;
|
729
|
+
base_scope.constructor[name] = value;
|
730
|
+
}
|
731
|
+
|
615
732
|
base_scope.constants.push(name);
|
616
733
|
return base_scope[name] = value;
|
617
734
|
};
|
@@ -631,6 +748,60 @@
|
|
631
748
|
}
|
632
749
|
};
|
633
750
|
|
751
|
+
/*
|
752
|
+
* Donate methods for a module.
|
753
|
+
*/
|
754
|
+
function donate(module, jsid) {
|
755
|
+
var included_in = module.$$dep,
|
756
|
+
body = module.$$proto[jsid],
|
757
|
+
i, length, includee, dest, current,
|
758
|
+
klass_includees, j, jj, current_owner_index, module_index;
|
759
|
+
|
760
|
+
if (!included_in) {
|
761
|
+
return;
|
762
|
+
}
|
763
|
+
|
764
|
+
for (i = 0, length = included_in.length; i < length; i++) {
|
765
|
+
includee = included_in[i];
|
766
|
+
dest = includee.$$proto;
|
767
|
+
current = dest[jsid];
|
768
|
+
|
769
|
+
if (dest.hasOwnProperty(jsid) && !current.$$donated && !current.$$stub) {
|
770
|
+
// target class has already defined the same method name - do nothing
|
771
|
+
}
|
772
|
+
else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
|
773
|
+
// target class includes another module that has defined this method
|
774
|
+
klass_includees = includee.$$inc;
|
775
|
+
|
776
|
+
for (j = 0, jj = klass_includees.length; j < jj; j++) {
|
777
|
+
if (klass_includees[j] === current.$$donated) {
|
778
|
+
current_owner_index = j;
|
779
|
+
}
|
780
|
+
if (klass_includees[j] === module) {
|
781
|
+
module_index = j;
|
782
|
+
}
|
783
|
+
}
|
784
|
+
|
785
|
+
// only redefine method on class if the module was included AFTER
|
786
|
+
// the module which defined the current method body. Also make sure
|
787
|
+
// a module can overwrite a method it defined before
|
788
|
+
if (current_owner_index <= module_index) {
|
789
|
+
dest[jsid] = body;
|
790
|
+
dest[jsid].$$donated = module;
|
791
|
+
}
|
792
|
+
}
|
793
|
+
else {
|
794
|
+
// neither a class, or module included by class, has defined method
|
795
|
+
dest[jsid] = body;
|
796
|
+
dest[jsid].$$donated = module;
|
797
|
+
}
|
798
|
+
|
799
|
+
if (includee.$$dep) {
|
800
|
+
donate(includee, jsid);
|
801
|
+
}
|
802
|
+
}
|
803
|
+
};
|
804
|
+
|
634
805
|
/*
|
635
806
|
* Methods stubs are used to facilitate method_missing in opal. A stub is a
|
636
807
|
* placeholder function which just calls `method_missing` on the receiver.
|
@@ -660,14 +831,18 @@
|
|
660
831
|
* @param [Array] stubs an array of method stubs to add
|
661
832
|
*/
|
662
833
|
Opal.add_stubs = function(stubs) {
|
663
|
-
var subscribers = Opal.stub_subscribers
|
664
|
-
|
834
|
+
var subscriber, subscribers = Opal.stub_subscribers,
|
835
|
+
i, ilength = stubs.length,
|
836
|
+
j, jlength = subscribers.length,
|
837
|
+
method_name, stub;
|
665
838
|
|
666
|
-
for (
|
667
|
-
|
839
|
+
for (i = 0; i < ilength; i++) {
|
840
|
+
method_name = stubs[i];
|
841
|
+
stub = stub_for(method_name);
|
668
842
|
|
669
|
-
for (
|
843
|
+
for (j = 0; j < jlength; j++) {
|
670
844
|
subscriber = subscribers[j];
|
845
|
+
|
671
846
|
if (!(method_name in subscriber)) {
|
672
847
|
subscriber[method_name] = stub;
|
673
848
|
}
|
@@ -675,17 +850,6 @@
|
|
675
850
|
}
|
676
851
|
};
|
677
852
|
|
678
|
-
/*
|
679
|
-
* Add a prototype to the subscribers list, and (TODO) add previously stubbed
|
680
|
-
* methods.
|
681
|
-
*
|
682
|
-
* @param [Prototype]
|
683
|
-
*/
|
684
|
-
function add_stubs_subscriber(prototype) {
|
685
|
-
// TODO: Add previously stubbed methods too.
|
686
|
-
Opal.stub_subscribers.push(prototype);
|
687
|
-
}
|
688
|
-
|
689
853
|
/*
|
690
854
|
* Keep a list of prototypes that want method_missing stubs to be added.
|
691
855
|
*
|
@@ -732,9 +896,16 @@
|
|
732
896
|
|
733
897
|
// Arity count error dispatcher
|
734
898
|
Opal.ac = function(actual, expected, object, meth) {
|
735
|
-
var inspect =
|
736
|
-
|
737
|
-
|
899
|
+
var inspect = '';
|
900
|
+
if (object.$$is_class || object.$$is_module) {
|
901
|
+
inspect += object.$$name + '.';
|
902
|
+
}
|
903
|
+
else {
|
904
|
+
inspect += object.$$class.$$name + '#';
|
905
|
+
}
|
906
|
+
inspect += meth;
|
907
|
+
|
908
|
+
throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')');
|
738
909
|
};
|
739
910
|
|
740
911
|
// Super dispatcher
|
@@ -742,10 +913,15 @@
|
|
742
913
|
var dispatcher;
|
743
914
|
|
744
915
|
if (defs) {
|
745
|
-
|
916
|
+
if (obj.$$is_class || obj.$$is_module) {
|
917
|
+
dispatcher = defs.$$super;
|
918
|
+
}
|
919
|
+
else {
|
920
|
+
dispatcher = obj.$$class.$$proto;
|
921
|
+
}
|
746
922
|
}
|
747
923
|
else {
|
748
|
-
if (obj.$$is_class) {
|
924
|
+
if (obj.$$is_class || obj.$$is_module) {
|
749
925
|
dispatcher = obj.$$super;
|
750
926
|
}
|
751
927
|
else {
|
@@ -837,7 +1013,7 @@
|
|
837
1013
|
throw Opal.LocalJumpError.$new("no block given");
|
838
1014
|
}
|
839
1015
|
|
840
|
-
if (block.length > 1 && args.length
|
1016
|
+
if (block.length > 1 && args.length === 1) {
|
841
1017
|
if (args[0].$$is_array) {
|
842
1018
|
return block.apply(null, args[0]);
|
843
1019
|
}
|
@@ -884,7 +1060,7 @@
|
|
884
1060
|
}
|
885
1061
|
|
886
1062
|
for (var i = 0, length = search.$$inc.length; i < length; i++) {
|
887
|
-
if (search.$$inc[i]
|
1063
|
+
if (search.$$inc[i] === klass) {
|
888
1064
|
return true;
|
889
1065
|
}
|
890
1066
|
}
|
@@ -903,8 +1079,21 @@
|
|
903
1079
|
else if (value.$to_ary && !value.$to_ary.$$stub) {
|
904
1080
|
return value.$to_ary();
|
905
1081
|
}
|
1082
|
+
else {
|
1083
|
+
return [value];
|
1084
|
+
}
|
1085
|
+
};
|
906
1086
|
|
907
|
-
|
1087
|
+
Opal.to_a = function(value) {
|
1088
|
+
if (value == null || value === nil) {
|
1089
|
+
return [];
|
1090
|
+
}
|
1091
|
+
else if (value.$to_a && !value.$to_a.$$stub) {
|
1092
|
+
return value.$to_a();
|
1093
|
+
}
|
1094
|
+
else {
|
1095
|
+
return [value];
|
1096
|
+
}
|
908
1097
|
};
|
909
1098
|
|
910
1099
|
/**
|
@@ -973,103 +1162,6 @@
|
|
973
1162
|
return recv.$method_missing.apply(recv, [mid].concat(args));
|
974
1163
|
};
|
975
1164
|
|
976
|
-
/*
|
977
|
-
* Donate methods for a class/module
|
978
|
-
*/
|
979
|
-
function donate_methods(klass, defined, indirect) {
|
980
|
-
var methods = klass.$$methods, included_in = klass.$$dep;
|
981
|
-
|
982
|
-
// if (!indirect) {
|
983
|
-
klass.$$methods = methods.concat(defined);
|
984
|
-
// }
|
985
|
-
|
986
|
-
if (included_in) {
|
987
|
-
for (var i = 0, length = included_in.length; i < length; i++) {
|
988
|
-
var includee = included_in[i];
|
989
|
-
var dest = includee.$$proto;
|
990
|
-
|
991
|
-
for (var j = 0, jj = defined.length; j < jj; j++) {
|
992
|
-
var method = defined[j];
|
993
|
-
|
994
|
-
dest[method] = klass.$$proto[method];
|
995
|
-
dest[method].$$donated = true;
|
996
|
-
}
|
997
|
-
|
998
|
-
if (includee.$$dep) {
|
999
|
-
donate_methods(includee, defined, true);
|
1000
|
-
}
|
1001
|
-
}
|
1002
|
-
}
|
1003
|
-
};
|
1004
|
-
|
1005
|
-
/**
|
1006
|
-
Define the given method on the module.
|
1007
|
-
|
1008
|
-
This also handles donating methods to all classes that include this
|
1009
|
-
module. Method conflicts are also handled here, where a class might already
|
1010
|
-
have defined a method of the same name, or another included module defined
|
1011
|
-
the same method.
|
1012
|
-
|
1013
|
-
@param [RubyModule] module the module method defined on
|
1014
|
-
@param [String] jsid javascript friendly method name (e.g. "$foo")
|
1015
|
-
@param [Function] body method body of actual function
|
1016
|
-
*/
|
1017
|
-
function define_module_method(module, jsid, body) {
|
1018
|
-
module.$$proto[jsid] = body;
|
1019
|
-
body.$$owner = module;
|
1020
|
-
|
1021
|
-
module.$$methods.push(jsid);
|
1022
|
-
|
1023
|
-
if (module.$$module_function) {
|
1024
|
-
module[jsid] = body;
|
1025
|
-
}
|
1026
|
-
|
1027
|
-
var included_in = module.$$dep;
|
1028
|
-
|
1029
|
-
if (included_in) {
|
1030
|
-
for (var i = 0, length = included_in.length; i < length; i++) {
|
1031
|
-
var includee = included_in[i];
|
1032
|
-
var dest = includee.$$proto;
|
1033
|
-
var current = dest[jsid];
|
1034
|
-
|
1035
|
-
|
1036
|
-
if (dest.hasOwnProperty(jsid) && !current.$$donated && !current.$$stub) {
|
1037
|
-
// target class has already defined the same method name - do nothing
|
1038
|
-
}
|
1039
|
-
else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
|
1040
|
-
// target class includes another module that has defined this method
|
1041
|
-
var klass_includees = includee.$$inc;
|
1042
|
-
|
1043
|
-
for (var j = 0, jj = klass_includees.length; j < jj; j++) {
|
1044
|
-
if (klass_includees[j] === current.$$owner) {
|
1045
|
-
var current_owner_index = j;
|
1046
|
-
}
|
1047
|
-
if (klass_includees[j] === module) {
|
1048
|
-
var module_index = j;
|
1049
|
-
}
|
1050
|
-
}
|
1051
|
-
|
1052
|
-
// only redefine method on class if the module was included AFTER
|
1053
|
-
// the module which defined the current method body. Also make sure
|
1054
|
-
// a module can overwrite a method it defined before
|
1055
|
-
if (current_owner_index <= module_index) {
|
1056
|
-
dest[jsid] = body;
|
1057
|
-
dest[jsid].$$donated = true;
|
1058
|
-
}
|
1059
|
-
}
|
1060
|
-
else {
|
1061
|
-
// neither a class, or module included by class, has defined method
|
1062
|
-
dest[jsid] = body;
|
1063
|
-
dest[jsid].$$donated = true;
|
1064
|
-
}
|
1065
|
-
|
1066
|
-
if (includee.$$dep) {
|
1067
|
-
donate_methods(includee, [jsid], true);
|
1068
|
-
}
|
1069
|
-
}
|
1070
|
-
}
|
1071
|
-
}
|
1072
|
-
|
1073
1165
|
/**
|
1074
1166
|
Used to define methods on an object. This is a helper method, used by the
|
1075
1167
|
compiled source to define methods on special case objects when the compiler
|
@@ -1108,21 +1200,33 @@
|
|
1108
1200
|
@returns [null]
|
1109
1201
|
*/
|
1110
1202
|
Opal.defn = function(obj, jsid, body) {
|
1111
|
-
|
1112
|
-
define_module_method(obj, jsid, body);
|
1113
|
-
}
|
1114
|
-
else if (obj.$$is_class) {
|
1115
|
-
obj.$$proto[jsid] = body;
|
1203
|
+
obj.$$proto[jsid] = body;
|
1116
1204
|
|
1117
|
-
|
1118
|
-
|
1205
|
+
if (obj.$$is_module) {
|
1206
|
+
donate(obj, jsid);
|
1207
|
+
|
1208
|
+
if (obj.$$module_function) {
|
1209
|
+
Opal.defs(obj, jsid, body);
|
1119
1210
|
}
|
1120
|
-
|
1121
|
-
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
if (obj.$__id__ && !obj.$__id__.$$stub) {
|
1214
|
+
var bridged = bridges[obj.$__id__()];
|
1215
|
+
|
1216
|
+
if (bridged) {
|
1217
|
+
for (var i = bridged.length - 1; i >= 0; i--) {
|
1218
|
+
bridge(bridged[i], obj, jsid, body);
|
1219
|
+
}
|
1122
1220
|
}
|
1123
1221
|
}
|
1124
|
-
|
1125
|
-
|
1222
|
+
|
1223
|
+
if (obj.$method_added && !obj.$method_added.$$stub) {
|
1224
|
+
obj.$method_added(jsid.substr(1));
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
var singleton_of = obj.$$singleton_of;
|
1228
|
+
if (singleton_of && singleton_of.$singleton_method_added && !singleton_of.$singleton_method_added.$$stub) {
|
1229
|
+
singleton_of.$singleton_method_added(jsid.substr(1));
|
1126
1230
|
}
|
1127
1231
|
|
1128
1232
|
return nil;
|
@@ -1132,105 +1236,381 @@
|
|
1132
1236
|
* Define a singleton method on the given object.
|
1133
1237
|
*/
|
1134
1238
|
Opal.defs = function(obj, jsid, body) {
|
1135
|
-
|
1136
|
-
|
1239
|
+
Opal.defn(Opal.get_singleton_class(obj), jsid, body)
|
1240
|
+
};
|
1241
|
+
|
1242
|
+
Opal.def = function(obj, jsid, body) {
|
1243
|
+
// if instance_eval is invoked on a module/class, it sets inst_eval_mod
|
1244
|
+
if (!obj.$$eval && (obj.$$is_class || obj.$$is_module)) {
|
1245
|
+
Opal.defn(obj, jsid, body);
|
1137
1246
|
}
|
1138
1247
|
else {
|
1139
|
-
obj
|
1248
|
+
Opal.defs(obj, jsid, body);
|
1140
1249
|
}
|
1141
1250
|
};
|
1142
1251
|
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1252
|
+
/*
|
1253
|
+
* Called from #remove_method.
|
1254
|
+
*/
|
1255
|
+
Opal.rdef = function(obj, jsid) {
|
1256
|
+
// TODO: remove from bridges as well
|
1257
|
+
|
1258
|
+
if (!$hasOwn.call(obj.$$proto, jsid)) {
|
1259
|
+
throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
|
1147
1260
|
}
|
1148
|
-
|
1261
|
+
|
1262
|
+
delete obj.$$proto[jsid];
|
1263
|
+
|
1264
|
+
if (obj.$$is_singleton) {
|
1265
|
+
if (obj.$$proto.$singleton_method_removed && !obj.$$proto.$singleton_method_removed.$$stub) {
|
1266
|
+
obj.$$proto.$singleton_method_removed(jsid.substr(1));
|
1267
|
+
}
|
1268
|
+
}
|
1269
|
+
else {
|
1270
|
+
if (obj.$method_removed && !obj.$method_removed.$$stub) {
|
1271
|
+
obj.$method_removed(jsid.substr(1));
|
1272
|
+
}
|
1273
|
+
}
|
1274
|
+
};
|
1149
1275
|
|
1150
1276
|
/*
|
1151
|
-
* Called
|
1277
|
+
* Called from #undef_method.
|
1152
1278
|
*/
|
1153
|
-
Opal.
|
1154
|
-
|
1279
|
+
Opal.udef = function(obj, jsid) {
|
1280
|
+
if (!obj.$$proto[jsid] || obj.$$proto[jsid].$$stub) {
|
1281
|
+
throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
|
1282
|
+
}
|
1283
|
+
|
1284
|
+
Opal.add_stub_for(obj.$$proto, jsid);
|
1285
|
+
|
1286
|
+
if (obj.$$is_singleton) {
|
1287
|
+
if (obj.$$proto.$singleton_method_undefined && !obj.$$proto.$singleton_method_undefined.$$stub) {
|
1288
|
+
obj.$$proto.$singleton_method_undefined(jsid.substr(1));
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
else {
|
1292
|
+
if (obj.$method_undefined && !obj.$method_undefined.$$stub) {
|
1293
|
+
obj.$method_undefined(jsid.substr(1));
|
1294
|
+
}
|
1295
|
+
}
|
1155
1296
|
};
|
1156
1297
|
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1298
|
+
// This black magic is required to avoid clashes of internal special fields,
|
1299
|
+
// like $$donated.
|
1300
|
+
function wrap(body) {
|
1301
|
+
function alias() {
|
1302
|
+
body.$$p = alias.$$p;
|
1303
|
+
body.$$s = alias.$$s;
|
1304
|
+
|
1305
|
+
try {
|
1306
|
+
return body.apply(this, $slice.call(arguments));
|
1307
|
+
}
|
1308
|
+
finally {
|
1309
|
+
alias.$$s = null;
|
1310
|
+
alias.$$p = null;
|
1311
|
+
}
|
1160
1312
|
}
|
1161
1313
|
|
1162
|
-
|
1163
|
-
|
1164
|
-
_map = {},
|
1165
|
-
smap = {},
|
1166
|
-
key, obj, length, khash, map;
|
1314
|
+
alias.$$target = body;
|
1315
|
+
alias.$$arity = body.length;
|
1167
1316
|
|
1168
|
-
|
1169
|
-
|
1170
|
-
hash.keys = keys;
|
1317
|
+
return alias;
|
1318
|
+
}
|
1171
1319
|
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1320
|
+
Opal.alias = function(obj, name, old) {
|
1321
|
+
var id = '$' + name,
|
1322
|
+
old_id = '$' + old,
|
1323
|
+
body = obj.$$proto['$' + old];
|
1324
|
+
|
1325
|
+
// instance_eval is being run on a class/module, so that need to alias class methods
|
1326
|
+
if (obj.$$eval) {
|
1327
|
+
return Opal.alias(Opal.get_singleton_class(obj), name, old);
|
1328
|
+
}
|
1175
1329
|
|
1176
|
-
|
1177
|
-
|
1330
|
+
if (typeof(body) !== "function" || body.$$stub) {
|
1331
|
+
var ancestor = obj.$$super;
|
1178
1332
|
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1333
|
+
while (typeof(body) !== "function" && ancestor) {
|
1334
|
+
body = ancestor[old_id];
|
1335
|
+
ancestor = ancestor.$$super;
|
1336
|
+
}
|
1182
1337
|
|
1183
|
-
|
1184
|
-
|
1338
|
+
if (typeof(body) !== "function" || body.$$stub) {
|
1339
|
+
throw Opal.NameError.$new("undefined method `" + old + "' for class `" + obj.$name() + "'")
|
1340
|
+
}
|
1341
|
+
}
|
1185
1342
|
|
1186
|
-
|
1187
|
-
khash = key;
|
1188
|
-
map = smap;
|
1189
|
-
} else {
|
1190
|
-
khash = key.$hash();
|
1191
|
-
map = _map;
|
1192
|
-
}
|
1343
|
+
Opal.defn(obj, id, wrap(body));
|
1193
1344
|
|
1194
|
-
|
1195
|
-
|
1196
|
-
}
|
1345
|
+
return obj;
|
1346
|
+
};
|
1197
1347
|
|
1198
|
-
|
1348
|
+
Opal.alias_native = function(obj, name, native_name) {
|
1349
|
+
var id = '$' + name,
|
1350
|
+
body = obj.$$proto[native_name];
|
1351
|
+
|
1352
|
+
if (typeof(body) !== "function" || body.$$stub) {
|
1353
|
+
throw Opal.NameError.$new("undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
Opal.defn(obj, id, wrap(body));
|
1357
|
+
|
1358
|
+
return obj;
|
1359
|
+
};
|
1360
|
+
|
1361
|
+
Opal.hash_init = function (hash) {
|
1362
|
+
hash.map = {};
|
1363
|
+
hash.smap = {};
|
1364
|
+
hash.keys = [];
|
1365
|
+
};
|
1366
|
+
|
1367
|
+
Opal.hash_clone = function (from_hash, to_hash) {
|
1368
|
+
to_hash.none = from_hash.none;
|
1369
|
+
to_hash.proc = from_hash.proc;
|
1370
|
+
|
1371
|
+
for (var i = 0, keys = from_hash.keys, length = keys.length, key, value; i < length; i++) {
|
1372
|
+
key = from_hash.keys[i];
|
1373
|
+
|
1374
|
+
if (key.$$is_string) {
|
1375
|
+
value = from_hash.smap[key];
|
1376
|
+
} else {
|
1377
|
+
value = key.value;
|
1378
|
+
key = key.key;
|
1379
|
+
}
|
1380
|
+
|
1381
|
+
Opal.hash_put(to_hash, key, value);
|
1382
|
+
}
|
1383
|
+
};
|
1384
|
+
|
1385
|
+
Opal.hash_put = function (hash, key, value) {
|
1386
|
+
if (key.$$is_string) {
|
1387
|
+
if (!hash.smap.hasOwnProperty(key)) {
|
1388
|
+
hash.keys.push(key);
|
1389
|
+
}
|
1390
|
+
hash.smap[key] = value;
|
1391
|
+
return;
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
var key_hash = key.$hash(), bucket, last_bucket;
|
1395
|
+
|
1396
|
+
if (!hash.map.hasOwnProperty(key_hash)) {
|
1397
|
+
bucket = {key: key, key_hash: key_hash, value: value};
|
1398
|
+
hash.keys.push(bucket);
|
1399
|
+
hash.map[key_hash] = bucket;
|
1400
|
+
return;
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
bucket = hash.map[key_hash];
|
1404
|
+
|
1405
|
+
while (bucket) {
|
1406
|
+
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
1407
|
+
last_bucket = undefined;
|
1408
|
+
bucket.value = value;
|
1409
|
+
break;
|
1410
|
+
}
|
1411
|
+
last_bucket = bucket;
|
1412
|
+
bucket = bucket.next;
|
1413
|
+
}
|
1414
|
+
|
1415
|
+
if (last_bucket) {
|
1416
|
+
bucket = {key: key, key_hash: key_hash, value: value};
|
1417
|
+
hash.keys.push(bucket);
|
1418
|
+
last_bucket.next = bucket;
|
1419
|
+
}
|
1420
|
+
};
|
1421
|
+
|
1422
|
+
Opal.hash_get = function (hash, key) {
|
1423
|
+
if (key.$$is_string) {
|
1424
|
+
if (hash.smap.hasOwnProperty(key)) {
|
1425
|
+
return hash.smap[key];
|
1426
|
+
}
|
1427
|
+
return;
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
var key_hash = key.$hash(), bucket;
|
1431
|
+
|
1432
|
+
if (hash.map.hasOwnProperty(key_hash)) {
|
1433
|
+
bucket = hash.map[key_hash];
|
1434
|
+
|
1435
|
+
while (bucket) {
|
1436
|
+
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
1437
|
+
return bucket.value;
|
1199
1438
|
}
|
1439
|
+
bucket = bucket.next;
|
1200
1440
|
}
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1441
|
+
}
|
1442
|
+
};
|
1443
|
+
|
1444
|
+
Opal.hash_delete = function (hash, key) {
|
1445
|
+
var i, keys = hash.keys, length = keys.length, value;
|
1446
|
+
|
1447
|
+
if (key.$$is_string) {
|
1448
|
+
if (!hash.smap.hasOwnProperty(key)) {
|
1449
|
+
return;
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
for (i = 0; i < length; i++) {
|
1453
|
+
if (keys[i] === key) {
|
1454
|
+
keys.splice(i, 1);
|
1455
|
+
break;
|
1207
1456
|
}
|
1208
1457
|
}
|
1458
|
+
|
1459
|
+
value = hash.smap[key];
|
1460
|
+
delete hash.smap[key];
|
1461
|
+
return value;
|
1209
1462
|
}
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1463
|
+
|
1464
|
+
var key_hash = key.$hash();
|
1465
|
+
|
1466
|
+
if (!hash.map.hasOwnProperty(key_hash)) {
|
1467
|
+
return;
|
1468
|
+
}
|
1469
|
+
|
1470
|
+
var bucket = hash.map[key_hash], last_bucket;
|
1471
|
+
|
1472
|
+
while (bucket) {
|
1473
|
+
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
1474
|
+
value = bucket.value;
|
1475
|
+
|
1476
|
+
for (i = 0; i < length; i++) {
|
1477
|
+
if (keys[i] === bucket) {
|
1478
|
+
keys.splice(i, 1);
|
1479
|
+
break;
|
1480
|
+
}
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
if (last_bucket && bucket.next) {
|
1484
|
+
last_bucket.next = bucket.next;
|
1485
|
+
}
|
1486
|
+
else if (last_bucket) {
|
1487
|
+
delete last_bucket.next;
|
1488
|
+
}
|
1489
|
+
else if (bucket.next) {
|
1490
|
+
hash.map[key_hash] = bucket.next;
|
1491
|
+
}
|
1492
|
+
else {
|
1493
|
+
delete hash.map[key_hash];
|
1494
|
+
}
|
1495
|
+
|
1496
|
+
return value;
|
1497
|
+
}
|
1498
|
+
last_bucket = bucket;
|
1499
|
+
bucket = bucket.next;
|
1500
|
+
}
|
1501
|
+
};
|
1502
|
+
|
1503
|
+
Opal.hash_rehash = function (hash) {
|
1504
|
+
for (var i = 0, length = hash.keys.length, key_hash, bucket, last_bucket; i < length; i++) {
|
1505
|
+
|
1506
|
+
if (hash.keys[i].$$is_string) {
|
1507
|
+
continue;
|
1214
1508
|
}
|
1215
1509
|
|
1216
|
-
|
1217
|
-
key = arguments[j];
|
1218
|
-
obj = arguments[++j];
|
1510
|
+
key_hash = hash.keys[i].key.$hash();
|
1219
1511
|
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1512
|
+
if (key_hash === hash.keys[i].key_hash) {
|
1513
|
+
continue;
|
1514
|
+
}
|
1515
|
+
|
1516
|
+
bucket = hash.map[hash.keys[i].key_hash];
|
1517
|
+
last_bucket = undefined;
|
1518
|
+
|
1519
|
+
while (bucket) {
|
1520
|
+
if (bucket === hash.keys[i]) {
|
1521
|
+
if (last_bucket && bucket.next) {
|
1522
|
+
last_bucket.next = bucket.next;
|
1523
|
+
}
|
1524
|
+
else if (last_bucket) {
|
1525
|
+
delete last_bucket.next;
|
1526
|
+
}
|
1527
|
+
else if (bucket.next) {
|
1528
|
+
hash.map[hash.keys[i].key_hash] = bucket.next;
|
1529
|
+
}
|
1530
|
+
else {
|
1531
|
+
delete hash.map[hash.keys[i].key_hash];
|
1532
|
+
}
|
1533
|
+
break;
|
1534
|
+
}
|
1535
|
+
last_bucket = bucket;
|
1536
|
+
bucket = bucket.next;
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
hash.keys[i].key_hash = key_hash;
|
1540
|
+
|
1541
|
+
if (!hash.map.hasOwnProperty(key_hash)) {
|
1542
|
+
hash.map[key_hash] = hash.keys[i];
|
1543
|
+
continue;
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
bucket = hash.map[key_hash];
|
1547
|
+
last_bucket = undefined;
|
1548
|
+
|
1549
|
+
while (bucket) {
|
1550
|
+
if (bucket === hash.keys[i]) {
|
1551
|
+
last_bucket = undefined;
|
1552
|
+
break;
|
1226
1553
|
}
|
1554
|
+
last_bucket = bucket;
|
1555
|
+
bucket = bucket.next;
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
if (last_bucket) {
|
1559
|
+
last_bucket.next = hash.keys[i];
|
1560
|
+
}
|
1561
|
+
}
|
1562
|
+
};
|
1563
|
+
|
1564
|
+
Opal.hash = function() {
|
1565
|
+
var arguments_length = arguments.length, args, hash, i, length, key, value;
|
1566
|
+
|
1567
|
+
if (arguments_length === 1 && arguments[0].$$is_hash) {
|
1568
|
+
return arguments[0];
|
1569
|
+
}
|
1570
|
+
|
1571
|
+
hash = new Opal.Hash.$$alloc();
|
1572
|
+
Opal.hash_init(hash);
|
1227
1573
|
|
1228
|
-
|
1229
|
-
|
1574
|
+
if (arguments_length === 1 && arguments[0].$$is_array) {
|
1575
|
+
args = arguments[0];
|
1576
|
+
length = args.length;
|
1577
|
+
|
1578
|
+
for (i = 0; i < length; i++) {
|
1579
|
+
if (args[i].length !== 2) {
|
1580
|
+
throw Opal.ArgumentError.$new("value not of length 2: " + args[i].$inspect());
|
1230
1581
|
}
|
1231
1582
|
|
1232
|
-
|
1583
|
+
key = args[i][0];
|
1584
|
+
value = args[i][1];
|
1585
|
+
|
1586
|
+
Opal.hash_put(hash, key, value);
|
1587
|
+
}
|
1588
|
+
|
1589
|
+
return hash;
|
1590
|
+
}
|
1591
|
+
|
1592
|
+
if (arguments_length === 1) {
|
1593
|
+
args = arguments[0];
|
1594
|
+
for (key in args) {
|
1595
|
+
if (args.hasOwnProperty(key)) {
|
1596
|
+
value = args[key];
|
1597
|
+
|
1598
|
+
Opal.hash_put(hash, key, value);
|
1599
|
+
}
|
1233
1600
|
}
|
1601
|
+
|
1602
|
+
return hash;
|
1603
|
+
}
|
1604
|
+
|
1605
|
+
if (arguments_length % 2 !== 0) {
|
1606
|
+
throw Opal.ArgumentError.$new("odd number of arguments for Hash");
|
1607
|
+
}
|
1608
|
+
|
1609
|
+
for (i = 0; i < arguments_length; i += 2) {
|
1610
|
+
key = arguments[i];
|
1611
|
+
value = arguments[i + 1];
|
1612
|
+
|
1613
|
+
Opal.hash_put(hash, key, value);
|
1234
1614
|
}
|
1235
1615
|
|
1236
1616
|
return hash;
|
@@ -1242,12 +1622,12 @@
|
|
1242
1622
|
* compile time, so they are just added here by the constructor
|
1243
1623
|
* function
|
1244
1624
|
*/
|
1245
|
-
Opal.hash2 = function(keys,
|
1625
|
+
Opal.hash2 = function(keys, smap) {
|
1246
1626
|
var hash = new Opal.Hash.$$alloc();
|
1247
1627
|
|
1248
|
-
hash.keys = keys;
|
1249
1628
|
hash.map = {};
|
1250
|
-
hash.
|
1629
|
+
hash.keys = keys;
|
1630
|
+
hash.smap = smap;
|
1251
1631
|
|
1252
1632
|
return hash;
|
1253
1633
|
};
|
@@ -1265,6 +1645,25 @@
|
|
1265
1645
|
return range;
|
1266
1646
|
};
|
1267
1647
|
|
1648
|
+
Opal.ivar = function(name) {
|
1649
|
+
if (name === "constructor" ||
|
1650
|
+
name === "__proto__" ||
|
1651
|
+
name === "__parent__" ||
|
1652
|
+
name === "__noSuchMethod__" ||
|
1653
|
+
name === "__count__")
|
1654
|
+
{
|
1655
|
+
return name + "$";
|
1656
|
+
}
|
1657
|
+
|
1658
|
+
if (name === "hasOwnProperty" ||
|
1659
|
+
name === "valueOf")
|
1660
|
+
{
|
1661
|
+
return name + "$";
|
1662
|
+
}
|
1663
|
+
|
1664
|
+
return name;
|
1665
|
+
};
|
1666
|
+
|
1268
1667
|
// Require system
|
1269
1668
|
// --------------
|
1270
1669
|
(function(Opal) {
|
@@ -1274,18 +1673,7 @@
|
|
1274
1673
|
|
1275
1674
|
var current_dir = '.';
|
1276
1675
|
|
1277
|
-
function
|
1278
|
-
if (require_table[filename]) {
|
1279
|
-
return false;
|
1280
|
-
}
|
1281
|
-
|
1282
|
-
loaded_features.push(filename);
|
1283
|
-
require_table[filename] = true;
|
1284
|
-
|
1285
|
-
return true;
|
1286
|
-
}
|
1287
|
-
|
1288
|
-
function normalize_loadable_path(path) {
|
1676
|
+
function normalize(path) {
|
1289
1677
|
var parts, part, new_parts = [], SEPARATOR = '/';
|
1290
1678
|
|
1291
1679
|
if (current_dir !== '.') {
|
@@ -1297,15 +1685,32 @@
|
|
1297
1685
|
|
1298
1686
|
for (var i = 0, ii = parts.length; i < ii; i++) {
|
1299
1687
|
part = parts[i];
|
1300
|
-
if (part
|
1688
|
+
if (part === '') continue;
|
1301
1689
|
(part === '..') ? new_parts.pop() : new_parts.push(part)
|
1302
1690
|
}
|
1303
1691
|
|
1304
1692
|
return new_parts.join(SEPARATOR);
|
1305
1693
|
}
|
1306
1694
|
|
1695
|
+
function loaded(paths) {
|
1696
|
+
var i, l, path;
|
1697
|
+
|
1698
|
+
for (i = 0, l = paths.length; i < l; i++) {
|
1699
|
+
path = normalize(paths[i]);
|
1700
|
+
|
1701
|
+
if (require_table[path]) {
|
1702
|
+
return;
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
loaded_features.push(path);
|
1706
|
+
require_table[path] = true;
|
1707
|
+
}
|
1708
|
+
}
|
1709
|
+
|
1307
1710
|
function load(path) {
|
1308
|
-
|
1711
|
+
path = normalize(path);
|
1712
|
+
|
1713
|
+
loaded([path]);
|
1309
1714
|
|
1310
1715
|
var module = modules[path];
|
1311
1716
|
|
@@ -1328,6 +1733,8 @@
|
|
1328
1733
|
}
|
1329
1734
|
|
1330
1735
|
function require(path) {
|
1736
|
+
path = normalize(path);
|
1737
|
+
|
1331
1738
|
if (require_table[path]) {
|
1332
1739
|
return false;
|
1333
1740
|
}
|
@@ -1337,9 +1744,7 @@
|
|
1337
1744
|
|
1338
1745
|
Opal.modules = modules;
|
1339
1746
|
Opal.loaded_features = loaded_features;
|
1340
|
-
|
1341
|
-
Opal.normalize_loadable_path = normalize_loadable_path;
|
1342
|
-
Opal.mark_as_loaded = mark_as_loaded;
|
1747
|
+
Opal.loaded = loaded;
|
1343
1748
|
|
1344
1749
|
Opal.load = load;
|
1345
1750
|
Opal.require = require;
|
@@ -1404,16 +1809,9 @@
|
|
1404
1809
|
ModuleClass.$$parent = ObjectClass;
|
1405
1810
|
ClassClass.$$parent = ModuleClass;
|
1406
1811
|
|
1407
|
-
// Internally, Object acts like a module as it is "included" into bridged
|
1408
|
-
// classes. In other words, we donate methods from Object into our bridged
|
1409
|
-
// classes as their prototypes don't inherit from our root Object, so they
|
1410
|
-
// act like module includes.
|
1411
|
-
ObjectClass.$$dep = bridged_classes;
|
1412
|
-
|
1413
1812
|
Opal.base = ObjectClass;
|
1414
1813
|
BasicObjectClass.$$scope = ObjectClass.$$scope = Opal;
|
1415
1814
|
BasicObjectClass.$$orig_scope = ObjectClass.$$orig_scope = Opal;
|
1416
|
-
Opal.Kernel = ObjectClass;
|
1417
1815
|
|
1418
1816
|
ModuleClass.$$scope = ObjectClass.$$scope;
|
1419
1817
|
ModuleClass.$$orig_scope = ObjectClass.$$orig_scope;
|
@@ -1437,15 +1835,6 @@
|
|
1437
1835
|
Opal.breaker = new Error('unexpected break');
|
1438
1836
|
Opal.returner = new Error('unexpected return');
|
1439
1837
|
|
1440
|
-
bridge_class('Array', Array);
|
1441
|
-
bridge_class('Boolean', Boolean);
|
1442
|
-
bridge_class('Numeric', Number);
|
1443
|
-
bridge_class('String', String);
|
1444
|
-
bridge_class('Proc', Function);
|
1445
|
-
bridge_class('Exception', Error);
|
1446
|
-
bridge_class('Regexp', RegExp);
|
1447
|
-
bridge_class('Time', Date);
|
1448
|
-
|
1449
1838
|
TypeError.$$super = Error;
|
1450
1839
|
}).call(this);
|
1451
1840
|
|