opal 1.7.3 → 1.8.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/.github/workflows/build.yml +9 -9
- data/.rubocop/todo.yml +2 -2
- data/.rubocop.yml +17 -10
- data/.rubocop_todo.yml +311 -0
- data/UNRELEASED.md +78 -1
- data/benchmark-ips/bm_block_vs_yield.rb +3 -0
- data/benchmark-ips/bm_slice_or_not.rb +53 -0
- data/docs/bridging.md +112 -0
- data/docs/compiled_ruby.md +10 -10
- data/docs/getting_started.md +18 -22
- data/lib/opal/cli_runners/chrome_cdp_interface.rb +1 -0
- data/lib/opal/cli_runners/firefox_cdp_interface.rb +1 -0
- data/lib/opal/compiler.rb +33 -1
- data/lib/opal/nodes/args/extract_kwoptarg.rb +2 -1
- data/lib/opal/nodes/call.rb +1 -1
- data/lib/opal/nodes/call_special.rb +71 -47
- data/lib/opal/nodes/hash.rb +14 -30
- data/lib/opal/nodes/if.rb +38 -30
- data/lib/opal/nodes/literal.rb +5 -1
- data/lib/opal/nodes/x_string.rb +13 -0
- data/lib/opal/parser/patch.rb +1 -0
- data/lib/opal/rewriters/for_rewriter.rb +36 -24
- data/lib/opal/source_map/file.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array/pack.rb +1 -0
- data/opal/corelib/array.rb +71 -43
- data/opal/corelib/basic_object.rb +1 -0
- data/opal/corelib/binding.rb +2 -0
- data/opal/corelib/boolean.rb +1 -0
- data/opal/corelib/class.rb +2 -0
- data/opal/corelib/comparable.rb +1 -0
- data/opal/corelib/complex.rb +2 -0
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/dir.rb +2 -0
- data/opal/corelib/enumerable.rb +3 -2
- data/opal/corelib/enumerator/arithmetic_sequence.rb +2 -0
- data/opal/corelib/enumerator/chain.rb +1 -0
- data/opal/corelib/enumerator/generator.rb +1 -0
- data/opal/corelib/enumerator/lazy.rb +1 -0
- data/opal/corelib/enumerator/yielder.rb +2 -0
- data/opal/corelib/enumerator.rb +1 -0
- data/opal/corelib/error/errno.rb +2 -0
- data/opal/corelib/error.rb +12 -0
- data/opal/corelib/file.rb +1 -0
- data/opal/corelib/hash.rb +197 -504
- data/opal/corelib/helpers.rb +1 -0
- data/opal/corelib/io.rb +2 -0
- data/opal/corelib/irb.rb +2 -0
- data/opal/corelib/kernel/format.rb +1 -0
- data/opal/corelib/kernel.rb +70 -14
- data/opal/corelib/main.rb +2 -0
- data/opal/corelib/marshal/read_buffer.rb +2 -0
- data/opal/corelib/marshal/write_buffer.rb +2 -0
- data/opal/corelib/math/polyfills.rb +2 -0
- data/opal/corelib/math.rb +1 -0
- data/opal/corelib/method.rb +2 -0
- data/opal/corelib/module.rb +1 -0
- data/opal/corelib/nil.rb +3 -1
- data/opal/corelib/number.rb +2 -0
- data/opal/corelib/numeric.rb +2 -0
- data/opal/corelib/object_space.rb +1 -0
- data/opal/corelib/pack_unpack/format_string_parser.rb +2 -0
- data/opal/corelib/proc.rb +30 -28
- data/opal/corelib/process.rb +2 -0
- data/opal/corelib/random/formatter.rb +2 -0
- data/opal/corelib/random/math_random.js.rb +2 -0
- data/opal/corelib/random/mersenne_twister.rb +2 -0
- data/opal/corelib/random/seedrandom.js.rb +2 -0
- data/opal/corelib/random.rb +1 -0
- data/opal/corelib/range.rb +34 -12
- data/opal/corelib/rational.rb +2 -0
- data/opal/corelib/regexp.rb +5 -1
- data/opal/corelib/runtime.js +185 -224
- data/opal/corelib/set.rb +2 -0
- data/opal/corelib/string/encoding.rb +3 -0
- data/opal/corelib/string/unpack.rb +2 -0
- data/opal/corelib/string.rb +20 -12
- data/opal/corelib/struct.rb +3 -1
- data/opal/corelib/time.rb +1 -0
- data/opal/corelib/trace_point.rb +2 -0
- data/opal/corelib/unsupported.rb +2 -0
- data/opal/corelib/variables.rb +2 -0
- data/opal.gemspec +2 -2
- data/spec/filters/bugs/array.rb +0 -2
- data/spec/filters/bugs/enumerable.rb +0 -3
- data/spec/filters/bugs/hash.rb +0 -13
- data/spec/filters/bugs/kernel.rb +0 -38
- data/spec/filters/bugs/range.rb +0 -1
- data/spec/filters/bugs/ruby-32.rb +0 -2
- data/spec/filters/bugs/string.rb +0 -1
- data/spec/filters/bugs/struct.rb +1 -5
- data/spec/filters/unsupported/hash.rb +1 -0
- data/spec/lib/compiler_spec.rb +24 -17
- data/spec/mspec-opal/formatters.rb +2 -0
- data/spec/mspec-opal/runner.rb +2 -0
- data/spec/opal/core/array/dup_spec.rb +2 -0
- data/spec/opal/core/exception_spec.rb +2 -0
- data/spec/opal/core/hash/internals_spec.rb +154 -206
- data/spec/opal/core/hash_spec.rb +2 -0
- data/spec/opal/core/iterable_props_spec.rb +2 -0
- data/spec/opal/core/kernel/at_exit_spec.rb +2 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -0
- data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +2 -0
- data/spec/opal/core/language/case_spec.rb +13 -0
- data/spec/opal/core/language/safe_navigator_spec.rb +2 -0
- data/spec/opal/core/language/xstring_send_spec.rb +15 -0
- data/spec/opal/core/language/xstring_spec.rb +2 -0
- data/spec/opal/core/language_spec.rb +2 -0
- data/spec/opal/core/module_spec.rb +44 -0
- data/spec/opal/core/number/to_i_spec.rb +2 -0
- data/spec/opal/core/object_id_spec.rb +2 -0
- data/spec/opal/core/regexp/match_spec.rb +2 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +38 -0
- data/spec/opal/core/runtime/constants_spec.rb +2 -0
- data/spec/opal/core/runtime/eval_spec.rb +2 -0
- data/spec/opal/core/runtime/exit_spec.rb +2 -0
- data/spec/opal/core/runtime/is_a_spec.rb +2 -0
- data/spec/opal/core/runtime/loaded_spec.rb +2 -0
- data/spec/opal/core/runtime/method_missing_spec.rb +2 -0
- data/spec/opal/core/runtime/rescue_spec.rb +2 -0
- data/spec/opal/core/runtime/string_spec.rb +2 -0
- data/spec/opal/core/runtime/truthy_spec.rb +2 -0
- data/spec/opal/core/runtime_spec.rb +2 -6
- data/spec/opal/core/string/to_sym_spec.rb +2 -0
- data/spec/opal/stdlib/js_spec.rb +2 -0
- data/spec/opal/stdlib/native/alias_native_spec.rb +2 -0
- data/spec/opal/stdlib/native/array_spec.rb +2 -0
- data/spec/opal/stdlib/native/date_spec.rb +2 -0
- data/spec/opal/stdlib/native/each_spec.rb +2 -0
- data/spec/opal/stdlib/native/element_reference_spec.rb +2 -0
- data/spec/opal/stdlib/native/exposure_spec.rb +2 -0
- data/spec/opal/stdlib/native/ext_spec.rb +2 -0
- data/spec/opal/stdlib/native/hash_spec.rb +30 -2
- data/spec/opal/stdlib/native/initialize_spec.rb +2 -0
- data/spec/opal/stdlib/native/method_missing_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_alias_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_class_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_module_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_reader_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_writer_spec.rb +2 -0
- data/spec/opal/stdlib/native/new_spec.rb +2 -0
- data/spec/opal/stdlib/native/struct_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/stdlib/await.rb +1 -0
- data/stdlib/base64.rb +2 -0
- data/stdlib/bigdecimal/bignumber.js.rb +2 -0
- data/stdlib/bigdecimal/util.rb +1 -0
- data/stdlib/bigdecimal.rb +2 -0
- data/stdlib/buffer/array.rb +2 -0
- data/stdlib/buffer/view.rb +2 -0
- data/stdlib/buffer.rb +2 -0
- data/stdlib/cgi.rb +14 -0
- data/stdlib/console.rb +2 -0
- data/stdlib/date/date_time.rb +2 -0
- data/stdlib/date.rb +2 -0
- data/stdlib/delegate.rb +2 -0
- data/stdlib/deno/base.rb +2 -0
- data/stdlib/deno/file.rb +2 -0
- data/stdlib/erb.rb +2 -0
- data/stdlib/gjs/io.rb +2 -0
- data/stdlib/gjs/kernel.rb +2 -0
- data/stdlib/headless_browser/base.rb +2 -0
- data/stdlib/headless_browser/file.rb +1 -0
- data/stdlib/headless_browser.rb +1 -0
- data/stdlib/js.rb +2 -0
- data/stdlib/json.rb +9 -15
- data/stdlib/logger.rb +2 -0
- data/stdlib/nashorn/file.rb +2 -0
- data/stdlib/nashorn/io.rb +2 -0
- data/stdlib/native.rb +48 -48
- data/stdlib/nodejs/base.rb +2 -0
- data/stdlib/nodejs/dir.rb +2 -0
- data/stdlib/nodejs/env.rb +2 -0
- data/stdlib/nodejs/file.rb +2 -0
- data/stdlib/nodejs/fileutils.rb +2 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/js-yaml-3-6-1.js +1 -1
- data/stdlib/nodejs/kernel.rb +2 -0
- data/stdlib/nodejs/open-uri.rb +2 -0
- data/stdlib/nodejs/pathname.rb +2 -0
- data/stdlib/nodejs/require.rb +2 -0
- data/stdlib/nodejs/yaml.rb +9 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal-parser.rb +8 -1
- data/stdlib/opal-platform.rb +2 -0
- data/stdlib/opal-replutils.rb +2 -0
- data/stdlib/open-uri.rb +4 -1
- data/stdlib/ostruct.rb +4 -2
- data/stdlib/pathname.rb +2 -0
- data/stdlib/pp.rb +1 -0
- data/stdlib/promise/v2.rb +2 -0
- data/stdlib/quickjs/io.rb +2 -0
- data/stdlib/quickjs/kernel.rb +2 -0
- data/stdlib/quickjs.rb +2 -0
- data/stdlib/securerandom.rb +2 -0
- data/stdlib/strscan.rb +2 -0
- data/stdlib/time.rb +2 -0
- data/stdlib/uri.rb +1 -0
- data/tasks/performance/optimization_status.rb +2 -0
- data/tasks/testing.rake +1 -0
- data/test/nodejs/test_await.rb +1 -0
- data/test/nodejs/test_dir.rb +2 -0
- data/test/nodejs/test_error.rb +2 -0
- data/test/nodejs/test_file.rb +2 -0
- data/test/nodejs/test_string.rb +2 -0
- data/test/nodejs/test_yaml.rb +20 -0
- metadata +23 -13
- data/spec/filters/bugs/openstruct.rb +0 -8
data/opal/corelib/runtime.js
CHANGED
@@ -538,6 +538,13 @@
|
|
538
538
|
Opal.$$$ = Opal.const_get_qualified;
|
539
539
|
Opal.$r = Opal.const_get_relative_factory;
|
540
540
|
|
541
|
+
function descends_from_bridged_class(klass) {
|
542
|
+
if (klass == null) return false;
|
543
|
+
if (klass.$$bridge) return klass;
|
544
|
+
if (klass.$$super) return descends_from_bridged_class(klass.$$super);
|
545
|
+
return false;
|
546
|
+
}
|
547
|
+
|
541
548
|
// Modules & Classes
|
542
549
|
// -----------------
|
543
550
|
|
@@ -567,14 +574,13 @@
|
|
567
574
|
// @return new [Class] or existing ruby class
|
568
575
|
//
|
569
576
|
function $allocate_class(name, superclass, singleton) {
|
570
|
-
var klass;
|
577
|
+
var klass, bridged_descendant;
|
571
578
|
|
572
|
-
if (
|
579
|
+
if (bridged_descendant = descends_from_bridged_class(superclass)) {
|
573
580
|
// Inheritance from bridged classes requires
|
574
581
|
// calling original JS constructors
|
575
582
|
klass = function() {
|
576
|
-
var
|
577
|
-
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
|
583
|
+
var self = new ($bind.apply(bridged_descendant.$$constructor, $prepend(null, arguments)))();
|
578
584
|
|
579
585
|
// and replacing a __proto__ manually
|
580
586
|
$set_proto(self, klass.$$prototype);
|
@@ -1538,7 +1544,6 @@
|
|
1538
1544
|
// @param method_name [String] The js-name of the method to stub (e.g. "$foo")
|
1539
1545
|
// @return [undefined]
|
1540
1546
|
Opal.stub_for = function(method_name) {
|
1541
|
-
|
1542
1547
|
function method_missing_stub() {
|
1543
1548
|
// Copy any given block onto the method_missing dispatcher
|
1544
1549
|
this.$method_missing.$$p = method_missing_stub.$$p;
|
@@ -1547,11 +1552,8 @@
|
|
1547
1552
|
method_missing_stub.$$p = null;
|
1548
1553
|
|
1549
1554
|
// call method missing with correct args (remove '$' prefix on method name)
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
return this.$method_missing.apply(this, [method_name.slice(1)].concat(args_ary));
|
1554
|
-
}
|
1555
|
+
return this.$method_missing.apply(this, $prepend(method_name.slice(1), arguments));
|
1556
|
+
};
|
1555
1557
|
|
1556
1558
|
method_missing_stub.$$stub = true;
|
1557
1559
|
|
@@ -1693,13 +1695,6 @@
|
|
1693
1695
|
}
|
1694
1696
|
}
|
1695
1697
|
|
1696
|
-
if (!args.$$is_array) {
|
1697
|
-
var args_ary = new Array(args.length);
|
1698
|
-
for(var i = 0, l = args_ary.length; i < l; i++) { args_ary[i] = args[i]; }
|
1699
|
-
|
1700
|
-
return block.apply(null, args_ary);
|
1701
|
-
}
|
1702
|
-
|
1703
1698
|
return block.apply(null, args);
|
1704
1699
|
};
|
1705
1700
|
|
@@ -1812,11 +1807,10 @@
|
|
1812
1807
|
};
|
1813
1808
|
|
1814
1809
|
// Used for extracting keyword arguments from arguments passed to
|
1815
|
-
// JS function.
|
1816
|
-
// as a last item, returns a blank Hash.
|
1810
|
+
// JS function.
|
1817
1811
|
//
|
1818
1812
|
// @param parameters [Array]
|
1819
|
-
// @return [Hash]
|
1813
|
+
// @return [Hash] or undefined
|
1820
1814
|
//
|
1821
1815
|
Opal.extract_kwargs = function(parameters) {
|
1822
1816
|
var kwargs = parameters[parameters.length - 1];
|
@@ -1828,7 +1822,7 @@
|
|
1828
1822
|
|
1829
1823
|
// Used to get a list of rest keyword arguments. Method takes the given
|
1830
1824
|
// keyword args, i.e. the hash literal passed to the method containing all
|
1831
|
-
// keyword
|
1825
|
+
// keyword arguments passed to method, as well as the used args which are
|
1832
1826
|
// the names of required and optional arguments defined. This method then
|
1833
1827
|
// just returns all key/value pairs which have not been used, in a new
|
1834
1828
|
// hash literal.
|
@@ -1838,19 +1832,16 @@
|
|
1838
1832
|
// @return [Hash]
|
1839
1833
|
//
|
1840
1834
|
Opal.kwrestargs = function(given_args, used_args) {
|
1841
|
-
var
|
1842
|
-
map = {},
|
1843
|
-
key ,
|
1844
|
-
given_map = given_args.$$smap;
|
1835
|
+
var map = new Map();
|
1845
1836
|
|
1846
|
-
|
1837
|
+
Opal.hash_each(given_args, false, function(key, value) {
|
1847
1838
|
if (!used_args[key]) {
|
1848
|
-
|
1849
|
-
map[key] = given_map[key];
|
1839
|
+
Opal.hash_put(map, key, value);
|
1850
1840
|
}
|
1851
|
-
|
1841
|
+
return [false, false];
|
1842
|
+
});
|
1852
1843
|
|
1853
|
-
return
|
1844
|
+
return map;
|
1854
1845
|
};
|
1855
1846
|
|
1856
1847
|
function apply_blockopts(block, blockopts) {
|
@@ -1869,6 +1860,11 @@
|
|
1869
1860
|
}
|
1870
1861
|
Opal.jsid = $jsid;
|
1871
1862
|
|
1863
|
+
function $prepend(first, second) {
|
1864
|
+
if (!second.$$is_array) second = $slice(second);
|
1865
|
+
return [first].concat(second);
|
1866
|
+
}
|
1867
|
+
|
1872
1868
|
// Calls passed method on a ruby object with arguments and block:
|
1873
1869
|
//
|
1874
1870
|
// Can take a method or a method name.
|
@@ -1912,7 +1908,7 @@
|
|
1912
1908
|
Opal.send2 = function(recv, body, method, args, block, blockopts) {
|
1913
1909
|
if (body == null && method != null && recv.$method_missing) {
|
1914
1910
|
body = recv.$method_missing;
|
1915
|
-
args =
|
1911
|
+
args = $prepend(method, args);
|
1916
1912
|
}
|
1917
1913
|
|
1918
1914
|
apply_blockopts(block, blockopts);
|
@@ -2068,6 +2064,18 @@
|
|
2068
2064
|
return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
|
2069
2065
|
};
|
2070
2066
|
|
2067
|
+
// Since JavaScript has no concept of modules, we create proxy classes
|
2068
|
+
// called `iclasses` that store copies of methods loaded. We need to
|
2069
|
+
// update them if we remove a method.
|
2070
|
+
function remove_method_from_iclasses(obj, jsid) {
|
2071
|
+
if (obj.$$is_module) {
|
2072
|
+
for (var i = 0, iclasses = obj.$$iclasses, length = iclasses.length; i < length; i++) {
|
2073
|
+
var iclass = iclasses[i];
|
2074
|
+
delete iclass[jsid];
|
2075
|
+
}
|
2076
|
+
}
|
2077
|
+
}
|
2078
|
+
|
2071
2079
|
// Called from #remove_method.
|
2072
2080
|
Opal.rdef = function(obj, jsid) {
|
2073
2081
|
if (!$has_own(obj.$$prototype, jsid)) {
|
@@ -2076,6 +2084,8 @@
|
|
2076
2084
|
|
2077
2085
|
delete obj.$$prototype[jsid];
|
2078
2086
|
|
2087
|
+
remove_method_from_iclasses(obj, jsid);
|
2088
|
+
|
2079
2089
|
if (obj.$$is_singleton) {
|
2080
2090
|
if (obj.$$prototype.$singleton_method_removed && !obj.$$prototype.$singleton_method_removed.$$stub) {
|
2081
2091
|
obj.$$prototype.$singleton_method_removed(jsid.substr(1));
|
@@ -2096,6 +2106,8 @@
|
|
2096
2106
|
|
2097
2107
|
Opal.add_stub_for(obj.$$prototype, jsid);
|
2098
2108
|
|
2109
|
+
remove_method_from_iclasses(obj, jsid);
|
2110
|
+
|
2099
2111
|
if (obj.$$is_singleton) {
|
2100
2112
|
if (obj.$$prototype.$singleton_method_undefined && !obj.$$prototype.$singleton_method_undefined.$$stub) {
|
2101
2113
|
obj.$$prototype.$singleton_method_undefined(jsid.substr(1));
|
@@ -2155,16 +2167,11 @@
|
|
2155
2167
|
// We need a wrapper because otherwise properties
|
2156
2168
|
// would be overwritten on the original body.
|
2157
2169
|
alias = function() {
|
2158
|
-
var block = alias.$$p,
|
2159
|
-
|
2160
|
-
args = new Array(arguments.length);
|
2161
|
-
for(i = 0, ii = arguments.length; i < ii; i++) {
|
2162
|
-
args[i] = arguments[i];
|
2163
|
-
}
|
2170
|
+
var block = alias.$$p, i, ii;
|
2164
2171
|
|
2165
2172
|
alias.$$p = null;
|
2166
2173
|
|
2167
|
-
return Opal.send(this, body,
|
2174
|
+
return Opal.send(this, body, arguments, block);
|
2168
2175
|
};
|
2169
2176
|
|
2170
2177
|
// Assign the 'length' value with defineProperty because
|
@@ -2220,228 +2227,169 @@
|
|
2220
2227
|
// Hashes
|
2221
2228
|
// ------
|
2222
2229
|
|
2223
|
-
Opal.hash_init = function(
|
2224
|
-
|
2225
|
-
|
2226
|
-
hash.$$keys = [];
|
2227
|
-
};
|
2230
|
+
Opal.hash_init = function (_hash) {
|
2231
|
+
console.warn("DEPRECATION: Opal.hash_init is deprecated and is now a no-op.");
|
2232
|
+
}
|
2228
2233
|
|
2229
2234
|
Opal.hash_clone = function(from_hash, to_hash) {
|
2230
2235
|
to_hash.$$none = from_hash.$$none;
|
2231
2236
|
to_hash.$$proc = from_hash.$$proc;
|
2232
2237
|
|
2233
|
-
|
2234
|
-
key = keys[i];
|
2235
|
-
|
2236
|
-
if (key.$$is_string) {
|
2237
|
-
value = smap[key];
|
2238
|
-
} else {
|
2239
|
-
value = key.value;
|
2240
|
-
key = key.key;
|
2241
|
-
}
|
2242
|
-
|
2238
|
+
return Opal.hash_each(from_hash, to_hash, function(key, value) {
|
2243
2239
|
Opal.hash_put(to_hash, key, value);
|
2244
|
-
|
2240
|
+
return [false, to_hash];
|
2241
|
+
});
|
2245
2242
|
};
|
2246
2243
|
|
2247
2244
|
Opal.hash_put = function(hash, key, value) {
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
hash
|
2253
|
-
|
2254
|
-
|
2245
|
+
var type = typeof key;
|
2246
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2247
|
+
hash.set(key, value)
|
2248
|
+
} else if (key.$$is_string) {
|
2249
|
+
hash.set(key.valueOf(), value);
|
2250
|
+
} else {
|
2251
|
+
if (!hash.$$keys)
|
2252
|
+
hash.$$keys = new Map();
|
2255
2253
|
|
2256
|
-
|
2257
|
-
|
2254
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2255
|
+
keys = hash.$$keys;
|
2258
2256
|
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
}
|
2257
|
+
if (!keys.has(key_hash)) {
|
2258
|
+
keys.set(key_hash, [key]);
|
2259
|
+
hash.set(key, value);
|
2260
|
+
return;
|
2261
|
+
}
|
2265
2262
|
|
2266
|
-
|
2263
|
+
var objects = keys.get(key_hash),
|
2264
|
+
object;
|
2267
2265
|
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2266
|
+
for (var i=0; i<objects.length; i++) {
|
2267
|
+
object = objects[0];
|
2268
|
+
if (key === object || key['$eql?'](object)) {
|
2269
|
+
hash.set(object, value);
|
2270
|
+
return;
|
2271
|
+
}
|
2273
2272
|
}
|
2274
|
-
last_bucket = bucket;
|
2275
|
-
bucket = bucket.next;
|
2276
|
-
}
|
2277
2273
|
|
2278
|
-
|
2279
|
-
|
2280
|
-
hash.$$keys.push(bucket);
|
2281
|
-
last_bucket.next = bucket;
|
2274
|
+
objects.push(key);
|
2275
|
+
hash.set(key, value);
|
2282
2276
|
}
|
2283
2277
|
};
|
2284
2278
|
|
2285
2279
|
Opal.hash_get = function(hash, key) {
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
while (bucket) {
|
2300
|
-
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
2301
|
-
return bucket.value;
|
2280
|
+
var type = typeof key;
|
2281
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2282
|
+
return hash.get(key)
|
2283
|
+
} else if (hash.$$keys) {
|
2284
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2285
|
+
objects = hash.$$keys.get(key_hash),
|
2286
|
+
object;
|
2287
|
+
|
2288
|
+
if (objects !== undefined) {
|
2289
|
+
for (var i=0; i<objects.length; i++) {
|
2290
|
+
object = objects[i];
|
2291
|
+
if (key === object || key['$eql?'](object))
|
2292
|
+
return hash.get(object);
|
2302
2293
|
}
|
2303
|
-
|
2294
|
+
} else if (key.$$is_string) {
|
2295
|
+
return hash.get(key_hash);
|
2304
2296
|
}
|
2297
|
+
} else if (key.$$is_string) {
|
2298
|
+
return hash.get(key.valueOf());
|
2305
2299
|
}
|
2306
2300
|
};
|
2307
2301
|
|
2308
|
-
|
2309
|
-
var
|
2310
|
-
|
2311
|
-
|
2312
|
-
if (typeof key !== "string") key = key.valueOf();
|
2313
|
-
|
2314
|
-
if (!$has_own(hash.$$smap, key)) {
|
2315
|
-
return;
|
2316
|
-
}
|
2317
|
-
|
2318
|
-
for (i = 0; i < length; i++) {
|
2319
|
-
key_tmp = keys[i];
|
2320
|
-
|
2321
|
-
if (key_tmp.$$is_string && typeof key_tmp !== "string") {
|
2322
|
-
key_tmp = key_tmp.valueOf();
|
2323
|
-
}
|
2324
|
-
|
2325
|
-
if (key_tmp === key) {
|
2326
|
-
keys.splice(i, 1);
|
2327
|
-
break;
|
2328
|
-
}
|
2329
|
-
}
|
2330
|
-
|
2331
|
-
value = hash.$$smap[key];
|
2332
|
-
delete hash.$$smap[key];
|
2302
|
+
function $hash_delete_stage2(hash, key) {
|
2303
|
+
var value = hash.get(key);
|
2304
|
+
if (value !== undefined) {
|
2305
|
+
hash.delete(key);
|
2333
2306
|
return value;
|
2334
2307
|
}
|
2308
|
+
}
|
2335
2309
|
|
2336
|
-
|
2337
|
-
|
2338
|
-
if (
|
2339
|
-
return;
|
2340
|
-
}
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
if (
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2310
|
+
Opal.hash_delete = function(hash, key) {
|
2311
|
+
var type = typeof key
|
2312
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2313
|
+
return $hash_delete_stage2(hash, key);
|
2314
|
+
} else if (hash.$$keys) {
|
2315
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2316
|
+
objects = hash.$$keys.get(key_hash),
|
2317
|
+
object;
|
2318
|
+
|
2319
|
+
if (objects !== undefined) {
|
2320
|
+
for (var i=0; i<objects.length; i++) {
|
2321
|
+
object = objects[i];
|
2322
|
+
if (key === object || key['$eql?'](object)) {
|
2323
|
+
objects.splice(i, 1);
|
2324
|
+
if (objects.length === 0)
|
2325
|
+
hash.$$keys.delete(key_hash);
|
2326
|
+
return $hash_delete_stage2(hash, object);
|
2352
2327
|
}
|
2353
2328
|
}
|
2354
|
-
|
2355
|
-
|
2356
|
-
last_bucket.next = bucket.next;
|
2357
|
-
}
|
2358
|
-
else if (last_bucket) {
|
2359
|
-
delete last_bucket.next;
|
2360
|
-
}
|
2361
|
-
else if (bucket.next) {
|
2362
|
-
hash.$$map[key_hash] = bucket.next;
|
2363
|
-
}
|
2364
|
-
else {
|
2365
|
-
delete hash.$$map[key_hash];
|
2366
|
-
}
|
2367
|
-
|
2368
|
-
return value;
|
2329
|
+
} else if (key.$$is_string) {
|
2330
|
+
return $hash_delete_stage2(hash, key_hash);
|
2369
2331
|
}
|
2370
|
-
|
2371
|
-
|
2332
|
+
} else if (key.$$is_string) {
|
2333
|
+
return $hash_delete_stage2(hash, key.valueOf());
|
2372
2334
|
}
|
2373
2335
|
};
|
2374
2336
|
|
2375
2337
|
Opal.hash_rehash = function(hash) {
|
2376
|
-
|
2338
|
+
var keys = hash.$$keys;
|
2377
2339
|
|
2378
|
-
|
2379
|
-
|
2380
|
-
}
|
2340
|
+
if (keys)
|
2341
|
+
keys.clear();
|
2381
2342
|
|
2382
|
-
|
2343
|
+
Opal.hash_each(hash, false, function(key, value) {
|
2344
|
+
var type = typeof key;
|
2345
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint")
|
2346
|
+
return [false, false]; // nothing to rehash
|
2383
2347
|
|
2384
|
-
|
2385
|
-
continue;
|
2386
|
-
}
|
2348
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash());
|
2387
2349
|
|
2388
|
-
|
2389
|
-
|
2350
|
+
if (!keys)
|
2351
|
+
hash.$$keys = keys = new Map();
|
2390
2352
|
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
last_bucket.next = bucket.next;
|
2395
|
-
}
|
2396
|
-
else if (last_bucket) {
|
2397
|
-
delete last_bucket.next;
|
2398
|
-
}
|
2399
|
-
else if (bucket.next) {
|
2400
|
-
hash.$$map[hash.$$keys[i].key_hash] = bucket.next;
|
2401
|
-
}
|
2402
|
-
else {
|
2403
|
-
delete hash.$$map[hash.$$keys[i].key_hash];
|
2404
|
-
}
|
2405
|
-
break;
|
2406
|
-
}
|
2407
|
-
last_bucket = bucket;
|
2408
|
-
bucket = bucket.next;
|
2353
|
+
if (!keys.has(key_hash)) {
|
2354
|
+
keys.set(key_hash, [key]);
|
2355
|
+
return [false, false];
|
2409
2356
|
}
|
2410
2357
|
|
2411
|
-
|
2358
|
+
var objects = keys.get(key_hash),
|
2359
|
+
objects_copy = $slice(objects),
|
2360
|
+
object;
|
2412
2361
|
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
2362
|
+
for (var i=0; i<objects_copy.length; i++) {
|
2363
|
+
object = objects_copy[i];
|
2364
|
+
if (key === object || key['$eql?'](object)) {
|
2365
|
+
// got a duplicate, remove it
|
2366
|
+
objects.splice(objects.indexOf(object), 1);
|
2367
|
+
hash.delete(object);
|
2368
|
+
}
|
2416
2369
|
}
|
2417
2370
|
|
2418
|
-
|
2419
|
-
last_bucket = undefined;
|
2371
|
+
objects.push(key);
|
2420
2372
|
|
2421
|
-
|
2422
|
-
|
2423
|
-
last_bucket = undefined;
|
2424
|
-
break;
|
2425
|
-
}
|
2426
|
-
last_bucket = bucket;
|
2427
|
-
bucket = bucket.next;
|
2428
|
-
}
|
2373
|
+
return [false, false]
|
2374
|
+
});
|
2429
2375
|
|
2430
|
-
|
2431
|
-
last_bucket.next = hash.$$keys[i];
|
2432
|
-
}
|
2433
|
-
}
|
2376
|
+
return hash;
|
2434
2377
|
};
|
2435
2378
|
|
2436
|
-
Opal.hash = function() {
|
2437
|
-
var arguments_length = arguments.length,
|
2379
|
+
Opal.hash = function () {
|
2380
|
+
var arguments_length = arguments.length,
|
2381
|
+
args,
|
2382
|
+
hash,
|
2383
|
+
i,
|
2384
|
+
length,
|
2385
|
+
key,
|
2386
|
+
value;
|
2438
2387
|
|
2439
2388
|
if (arguments_length === 1 && arguments[0].$$is_hash) {
|
2440
2389
|
return arguments[0];
|
2441
2390
|
}
|
2442
2391
|
|
2443
|
-
hash = new
|
2444
|
-
Opal.hash_init(hash);
|
2392
|
+
hash = new Map();
|
2445
2393
|
|
2446
2394
|
if (arguments_length === 1) {
|
2447
2395
|
args = arguments[0];
|
@@ -2451,7 +2399,7 @@
|
|
2451
2399
|
|
2452
2400
|
for (i = 0; i < length; i++) {
|
2453
2401
|
if (args[i].length !== 2) {
|
2454
|
-
$raise(Opal.ArgumentError,
|
2402
|
+
$raise(Opal.ArgumentError, 'value not of length 2: ' + args[i].$inspect());
|
2455
2403
|
}
|
2456
2404
|
|
2457
2405
|
key = args[i][0];
|
@@ -2461,8 +2409,7 @@
|
|
2461
2409
|
}
|
2462
2410
|
|
2463
2411
|
return hash;
|
2464
|
-
}
|
2465
|
-
else {
|
2412
|
+
} else {
|
2466
2413
|
args = arguments[0];
|
2467
2414
|
for (key in args) {
|
2468
2415
|
if ($has_own(args, key)) {
|
@@ -2477,7 +2424,7 @@
|
|
2477
2424
|
}
|
2478
2425
|
|
2479
2426
|
if (arguments_length % 2 !== 0) {
|
2480
|
-
$raise(Opal.ArgumentError,
|
2427
|
+
$raise(Opal.ArgumentError, 'odd number of arguments for Hash');
|
2481
2428
|
}
|
2482
2429
|
|
2483
2430
|
for (i = 0; i < arguments_length; i += 2) {
|
@@ -2496,15 +2443,29 @@
|
|
2496
2443
|
// function.
|
2497
2444
|
//
|
2498
2445
|
Opal.hash2 = function(keys, smap) {
|
2499
|
-
|
2500
|
-
|
2501
|
-
hash.$$smap = smap;
|
2502
|
-
hash.$$map = Object.create(null);
|
2503
|
-
hash.$$keys = keys;
|
2446
|
+
console.warn("DEPRECATION: `Opal.hash2` is deprecated and will be removed in Opal 2.0. Use `new Map()` with an array of key/value pairs instead.");
|
2504
2447
|
|
2448
|
+
var hash = new Map();
|
2449
|
+
for (var i = 0, max = keys.length; i < max; i++) {
|
2450
|
+
hash.set(keys[i], smap[keys[i]]);
|
2451
|
+
}
|
2505
2452
|
return hash;
|
2506
2453
|
};
|
2507
2454
|
|
2455
|
+
Opal.hash_each = function (hash, dres, fun) {
|
2456
|
+
// dres = default result, returned if hash is empty
|
2457
|
+
// fun is called as fun(key, value) and must return a array with [break, result]
|
2458
|
+
// if break is true, iteration stops and result is returned
|
2459
|
+
// if break is false, iteration continues and eventually the last result is returned
|
2460
|
+
var res;
|
2461
|
+
for (var i = 0, entry, entries = Array.from(hash.entries()), l = entries.length; i < l; i++) {
|
2462
|
+
entry = entries[i];
|
2463
|
+
res = fun(entry[0], entry[1]);
|
2464
|
+
if (res[0]) return res[1];
|
2465
|
+
}
|
2466
|
+
return res ? res[1] : dres;
|
2467
|
+
};
|
2468
|
+
|
2508
2469
|
// Create a new range instance with first and last values, and whether the
|
2509
2470
|
// range excludes the last value.
|
2510
2471
|
//
|
@@ -2542,7 +2503,7 @@
|
|
2542
2503
|
// helper that can be used from methods
|
2543
2504
|
function $deny_frozen_access(obj) {
|
2544
2505
|
if (obj.$$frozen) {
|
2545
|
-
$raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj),
|
2506
|
+
$raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj), new Map([["receiver", obj]]));
|
2546
2507
|
}
|
2547
2508
|
};
|
2548
2509
|
Opal.deny_frozen_access = $deny_frozen_access;
|
@@ -2667,7 +2628,7 @@
|
|
2667
2628
|
if (part.ignoreCase !== ignoreCase)
|
2668
2629
|
Opal.Kernel.$warn(
|
2669
2630
|
"ignore case doesn't match for " + part.source.$inspect(),
|
2670
|
-
|
2631
|
+
new Map([['uplevel', 1]])
|
2671
2632
|
)
|
2672
2633
|
|
2673
2634
|
part = part.source;
|
@@ -2918,7 +2879,7 @@
|
|
2918
2879
|
// Primitives for handling parameters
|
2919
2880
|
Opal.ensure_kwargs = function(kwargs) {
|
2920
2881
|
if (kwargs == null) {
|
2921
|
-
return
|
2882
|
+
return new Map();
|
2922
2883
|
} else if (kwargs.$$is_hash) {
|
2923
2884
|
return kwargs;
|
2924
2885
|
} else {
|
@@ -2927,10 +2888,11 @@
|
|
2927
2888
|
}
|
2928
2889
|
|
2929
2890
|
Opal.get_kwarg = function(kwargs, key) {
|
2930
|
-
|
2891
|
+
var kwarg = Opal.hash_get(kwargs, key);
|
2892
|
+
if (kwarg === undefined) {
|
2931
2893
|
$raise(Opal.ArgumentError, 'missing keyword: '+key);
|
2932
2894
|
}
|
2933
|
-
return
|
2895
|
+
return kwarg;
|
2934
2896
|
}
|
2935
2897
|
|
2936
2898
|
// Arrays of size > 32 elements that contain only strings,
|
@@ -3015,10 +2977,9 @@
|
|
3015
2977
|
|
3016
2978
|
// Foward calls to define_method on the top object to Object
|
3017
2979
|
function top_define_method() {
|
3018
|
-
var args = $slice(arguments);
|
3019
2980
|
var block = top_define_method.$$p;
|
3020
2981
|
top_define_method.$$p = null;
|
3021
|
-
return Opal.send(_Object, 'define_method',
|
2982
|
+
return Opal.send(_Object, 'define_method', arguments, block)
|
3022
2983
|
};
|
3023
2984
|
|
3024
2985
|
// Nil
|
@@ -3032,7 +2993,7 @@
|
|
3032
2993
|
Object.seal(nil);
|
3033
2994
|
|
3034
2995
|
Opal.thrower = function(type) {
|
3035
|
-
var thrower =
|
2996
|
+
var thrower = { message: 'unexpected '+type };
|
3036
2997
|
thrower.$thrower_type = type;
|
3037
2998
|
thrower.$throw = function(value) {
|
3038
2999
|
if (value == null) value = nil;
|
data/opal/corelib/set.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# backtick_javascript: true
|
2
|
+
|
1
3
|
require 'corelib/string'
|
2
4
|
|
3
5
|
class ::Encoding
|
@@ -103,6 +105,7 @@ class ::Encoding
|
|
103
105
|
|
104
106
|
class ::EncodingError < ::StandardError; end
|
105
107
|
class ::CompatibilityError < ::EncodingError; end
|
108
|
+
class UndefinedConversionError < ::EncodingError; end
|
106
109
|
end
|
107
110
|
|
108
111
|
::Encoding.register 'UTF-8', aliases: ['CP65001'], ascii: true do
|