opal 1.7.4 → 1.8.0.alpha1
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/.github/workflows/build.yml +9 -9
- data/.rubocop/todo.yml +2 -2
- data/.rubocop.yml +17 -10
- data/.rubocop_todo.yml +311 -0
- data/CHANGELOG.md +1 -15
- 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.rb +1 -5
- 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 +37 -29
- 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/simple_server.rb +2 -2
- 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 +1 -0
- data/opal/corelib/runtime.js +187 -231
- 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/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 +22 -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) {
|
@@ -1863,17 +1854,17 @@
|
|
1863
1854
|
}
|
1864
1855
|
|
1865
1856
|
// Optimization for a costly operation of prepending '$' to method names
|
1866
|
-
var jsid_cache =
|
1857
|
+
var jsid_cache = {}
|
1867
1858
|
function $jsid(name) {
|
1868
|
-
|
1869
|
-
if (!jsid) {
|
1870
|
-
jsid = '$' + name;
|
1871
|
-
jsid_cache.set(name, jsid);
|
1872
|
-
}
|
1873
|
-
return jsid;
|
1859
|
+
return jsid_cache[name] || (jsid_cache[name] = '$' + name);
|
1874
1860
|
}
|
1875
1861
|
Opal.jsid = $jsid;
|
1876
1862
|
|
1863
|
+
function $prepend(first, second) {
|
1864
|
+
if (!second.$$is_array) second = $slice(second);
|
1865
|
+
return [first].concat(second);
|
1866
|
+
}
|
1867
|
+
|
1877
1868
|
// Calls passed method on a ruby object with arguments and block:
|
1878
1869
|
//
|
1879
1870
|
// Can take a method or a method name.
|
@@ -1917,7 +1908,7 @@
|
|
1917
1908
|
Opal.send2 = function(recv, body, method, args, block, blockopts) {
|
1918
1909
|
if (body == null && method != null && recv.$method_missing) {
|
1919
1910
|
body = recv.$method_missing;
|
1920
|
-
args =
|
1911
|
+
args = $prepend(method, args);
|
1921
1912
|
}
|
1922
1913
|
|
1923
1914
|
apply_blockopts(block, blockopts);
|
@@ -2073,6 +2064,18 @@
|
|
2073
2064
|
return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
|
2074
2065
|
};
|
2075
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
|
+
|
2076
2079
|
// Called from #remove_method.
|
2077
2080
|
Opal.rdef = function(obj, jsid) {
|
2078
2081
|
if (!$has_own(obj.$$prototype, jsid)) {
|
@@ -2081,6 +2084,8 @@
|
|
2081
2084
|
|
2082
2085
|
delete obj.$$prototype[jsid];
|
2083
2086
|
|
2087
|
+
remove_method_from_iclasses(obj, jsid);
|
2088
|
+
|
2084
2089
|
if (obj.$$is_singleton) {
|
2085
2090
|
if (obj.$$prototype.$singleton_method_removed && !obj.$$prototype.$singleton_method_removed.$$stub) {
|
2086
2091
|
obj.$$prototype.$singleton_method_removed(jsid.substr(1));
|
@@ -2101,6 +2106,8 @@
|
|
2101
2106
|
|
2102
2107
|
Opal.add_stub_for(obj.$$prototype, jsid);
|
2103
2108
|
|
2109
|
+
remove_method_from_iclasses(obj, jsid);
|
2110
|
+
|
2104
2111
|
if (obj.$$is_singleton) {
|
2105
2112
|
if (obj.$$prototype.$singleton_method_undefined && !obj.$$prototype.$singleton_method_undefined.$$stub) {
|
2106
2113
|
obj.$$prototype.$singleton_method_undefined(jsid.substr(1));
|
@@ -2160,16 +2167,11 @@
|
|
2160
2167
|
// We need a wrapper because otherwise properties
|
2161
2168
|
// would be overwritten on the original body.
|
2162
2169
|
alias = function() {
|
2163
|
-
var block = alias.$$p,
|
2164
|
-
|
2165
|
-
args = new Array(arguments.length);
|
2166
|
-
for(i = 0, ii = arguments.length; i < ii; i++) {
|
2167
|
-
args[i] = arguments[i];
|
2168
|
-
}
|
2170
|
+
var block = alias.$$p, i, ii;
|
2169
2171
|
|
2170
2172
|
alias.$$p = null;
|
2171
2173
|
|
2172
|
-
return Opal.send(this, body,
|
2174
|
+
return Opal.send(this, body, arguments, block);
|
2173
2175
|
};
|
2174
2176
|
|
2175
2177
|
// Assign the 'length' value with defineProperty because
|
@@ -2225,228 +2227,169 @@
|
|
2225
2227
|
// Hashes
|
2226
2228
|
// ------
|
2227
2229
|
|
2228
|
-
Opal.hash_init = function(
|
2229
|
-
|
2230
|
-
|
2231
|
-
hash.$$keys = [];
|
2232
|
-
};
|
2230
|
+
Opal.hash_init = function (_hash) {
|
2231
|
+
console.warn("DEPRECATION: Opal.hash_init is deprecated and is now a no-op.");
|
2232
|
+
}
|
2233
2233
|
|
2234
2234
|
Opal.hash_clone = function(from_hash, to_hash) {
|
2235
2235
|
to_hash.$$none = from_hash.$$none;
|
2236
2236
|
to_hash.$$proc = from_hash.$$proc;
|
2237
2237
|
|
2238
|
-
|
2239
|
-
key = keys[i];
|
2240
|
-
|
2241
|
-
if (key.$$is_string) {
|
2242
|
-
value = smap[key];
|
2243
|
-
} else {
|
2244
|
-
value = key.value;
|
2245
|
-
key = key.key;
|
2246
|
-
}
|
2247
|
-
|
2238
|
+
return Opal.hash_each(from_hash, to_hash, function(key, value) {
|
2248
2239
|
Opal.hash_put(to_hash, key, value);
|
2249
|
-
|
2240
|
+
return [false, to_hash];
|
2241
|
+
});
|
2250
2242
|
};
|
2251
2243
|
|
2252
2244
|
Opal.hash_put = function(hash, key, value) {
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
hash
|
2258
|
-
|
2259
|
-
|
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();
|
2260
2253
|
|
2261
|
-
|
2262
|
-
|
2254
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2255
|
+
keys = hash.$$keys;
|
2263
2256
|
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
}
|
2257
|
+
if (!keys.has(key_hash)) {
|
2258
|
+
keys.set(key_hash, [key]);
|
2259
|
+
hash.set(key, value);
|
2260
|
+
return;
|
2261
|
+
}
|
2270
2262
|
|
2271
|
-
|
2263
|
+
var objects = keys.get(key_hash),
|
2264
|
+
object;
|
2272
2265
|
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
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
|
+
}
|
2278
2272
|
}
|
2279
|
-
last_bucket = bucket;
|
2280
|
-
bucket = bucket.next;
|
2281
|
-
}
|
2282
2273
|
|
2283
|
-
|
2284
|
-
|
2285
|
-
hash.$$keys.push(bucket);
|
2286
|
-
last_bucket.next = bucket;
|
2274
|
+
objects.push(key);
|
2275
|
+
hash.set(key, value);
|
2287
2276
|
}
|
2288
2277
|
};
|
2289
2278
|
|
2290
2279
|
Opal.hash_get = function(hash, key) {
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
while (bucket) {
|
2305
|
-
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
2306
|
-
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);
|
2307
2293
|
}
|
2308
|
-
|
2294
|
+
} else if (key.$$is_string) {
|
2295
|
+
return hash.get(key_hash);
|
2309
2296
|
}
|
2297
|
+
} else if (key.$$is_string) {
|
2298
|
+
return hash.get(key.valueOf());
|
2310
2299
|
}
|
2311
2300
|
};
|
2312
2301
|
|
2313
|
-
|
2314
|
-
var
|
2315
|
-
|
2316
|
-
|
2317
|
-
if (typeof key !== "string") key = key.valueOf();
|
2318
|
-
|
2319
|
-
if (!$has_own(hash.$$smap, key)) {
|
2320
|
-
return;
|
2321
|
-
}
|
2322
|
-
|
2323
|
-
for (i = 0; i < length; i++) {
|
2324
|
-
key_tmp = keys[i];
|
2325
|
-
|
2326
|
-
if (key_tmp.$$is_string && typeof key_tmp !== "string") {
|
2327
|
-
key_tmp = key_tmp.valueOf();
|
2328
|
-
}
|
2329
|
-
|
2330
|
-
if (key_tmp === key) {
|
2331
|
-
keys.splice(i, 1);
|
2332
|
-
break;
|
2333
|
-
}
|
2334
|
-
}
|
2335
|
-
|
2336
|
-
value = hash.$$smap[key];
|
2337
|
-
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);
|
2338
2306
|
return value;
|
2339
2307
|
}
|
2308
|
+
}
|
2340
2309
|
|
2341
|
-
|
2342
|
-
|
2343
|
-
if (
|
2344
|
-
return;
|
2345
|
-
}
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
if (
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
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);
|
2357
2327
|
}
|
2358
2328
|
}
|
2359
|
-
|
2360
|
-
|
2361
|
-
last_bucket.next = bucket.next;
|
2362
|
-
}
|
2363
|
-
else if (last_bucket) {
|
2364
|
-
delete last_bucket.next;
|
2365
|
-
}
|
2366
|
-
else if (bucket.next) {
|
2367
|
-
hash.$$map[key_hash] = bucket.next;
|
2368
|
-
}
|
2369
|
-
else {
|
2370
|
-
delete hash.$$map[key_hash];
|
2371
|
-
}
|
2372
|
-
|
2373
|
-
return value;
|
2329
|
+
} else if (key.$$is_string) {
|
2330
|
+
return $hash_delete_stage2(hash, key_hash);
|
2374
2331
|
}
|
2375
|
-
|
2376
|
-
|
2332
|
+
} else if (key.$$is_string) {
|
2333
|
+
return $hash_delete_stage2(hash, key.valueOf());
|
2377
2334
|
}
|
2378
2335
|
};
|
2379
2336
|
|
2380
2337
|
Opal.hash_rehash = function(hash) {
|
2381
|
-
|
2338
|
+
var keys = hash.$$keys;
|
2382
2339
|
|
2383
|
-
|
2384
|
-
|
2385
|
-
}
|
2340
|
+
if (keys)
|
2341
|
+
keys.clear();
|
2386
2342
|
|
2387
|
-
|
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
|
2388
2347
|
|
2389
|
-
|
2390
|
-
continue;
|
2391
|
-
}
|
2348
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash());
|
2392
2349
|
|
2393
|
-
|
2394
|
-
|
2350
|
+
if (!keys)
|
2351
|
+
hash.$$keys = keys = new Map();
|
2395
2352
|
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
last_bucket.next = bucket.next;
|
2400
|
-
}
|
2401
|
-
else if (last_bucket) {
|
2402
|
-
delete last_bucket.next;
|
2403
|
-
}
|
2404
|
-
else if (bucket.next) {
|
2405
|
-
hash.$$map[hash.$$keys[i].key_hash] = bucket.next;
|
2406
|
-
}
|
2407
|
-
else {
|
2408
|
-
delete hash.$$map[hash.$$keys[i].key_hash];
|
2409
|
-
}
|
2410
|
-
break;
|
2411
|
-
}
|
2412
|
-
last_bucket = bucket;
|
2413
|
-
bucket = bucket.next;
|
2353
|
+
if (!keys.has(key_hash)) {
|
2354
|
+
keys.set(key_hash, [key]);
|
2355
|
+
return [false, false];
|
2414
2356
|
}
|
2415
2357
|
|
2416
|
-
|
2358
|
+
var objects = keys.get(key_hash),
|
2359
|
+
objects_copy = $slice(objects),
|
2360
|
+
object;
|
2417
2361
|
|
2418
|
-
|
2419
|
-
|
2420
|
-
|
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
|
+
}
|
2421
2369
|
}
|
2422
2370
|
|
2423
|
-
|
2424
|
-
last_bucket = undefined;
|
2371
|
+
objects.push(key);
|
2425
2372
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
last_bucket = undefined;
|
2429
|
-
break;
|
2430
|
-
}
|
2431
|
-
last_bucket = bucket;
|
2432
|
-
bucket = bucket.next;
|
2433
|
-
}
|
2373
|
+
return [false, false]
|
2374
|
+
});
|
2434
2375
|
|
2435
|
-
|
2436
|
-
last_bucket.next = hash.$$keys[i];
|
2437
|
-
}
|
2438
|
-
}
|
2376
|
+
return hash;
|
2439
2377
|
};
|
2440
2378
|
|
2441
|
-
Opal.hash = function() {
|
2442
|
-
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;
|
2443
2387
|
|
2444
2388
|
if (arguments_length === 1 && arguments[0].$$is_hash) {
|
2445
2389
|
return arguments[0];
|
2446
2390
|
}
|
2447
2391
|
|
2448
|
-
hash = new
|
2449
|
-
Opal.hash_init(hash);
|
2392
|
+
hash = new Map();
|
2450
2393
|
|
2451
2394
|
if (arguments_length === 1) {
|
2452
2395
|
args = arguments[0];
|
@@ -2456,7 +2399,7 @@
|
|
2456
2399
|
|
2457
2400
|
for (i = 0; i < length; i++) {
|
2458
2401
|
if (args[i].length !== 2) {
|
2459
|
-
$raise(Opal.ArgumentError,
|
2402
|
+
$raise(Opal.ArgumentError, 'value not of length 2: ' + args[i].$inspect());
|
2460
2403
|
}
|
2461
2404
|
|
2462
2405
|
key = args[i][0];
|
@@ -2466,8 +2409,7 @@
|
|
2466
2409
|
}
|
2467
2410
|
|
2468
2411
|
return hash;
|
2469
|
-
}
|
2470
|
-
else {
|
2412
|
+
} else {
|
2471
2413
|
args = arguments[0];
|
2472
2414
|
for (key in args) {
|
2473
2415
|
if ($has_own(args, key)) {
|
@@ -2482,7 +2424,7 @@
|
|
2482
2424
|
}
|
2483
2425
|
|
2484
2426
|
if (arguments_length % 2 !== 0) {
|
2485
|
-
$raise(Opal.ArgumentError,
|
2427
|
+
$raise(Opal.ArgumentError, 'odd number of arguments for Hash');
|
2486
2428
|
}
|
2487
2429
|
|
2488
2430
|
for (i = 0; i < arguments_length; i += 2) {
|
@@ -2501,15 +2443,29 @@
|
|
2501
2443
|
// function.
|
2502
2444
|
//
|
2503
2445
|
Opal.hash2 = function(keys, smap) {
|
2504
|
-
|
2505
|
-
|
2506
|
-
hash.$$smap = smap;
|
2507
|
-
hash.$$map = Object.create(null);
|
2508
|
-
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.");
|
2509
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
|
+
}
|
2510
2452
|
return hash;
|
2511
2453
|
};
|
2512
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
|
+
|
2513
2469
|
// Create a new range instance with first and last values, and whether the
|
2514
2470
|
// range excludes the last value.
|
2515
2471
|
//
|
@@ -2547,7 +2503,7 @@
|
|
2547
2503
|
// helper that can be used from methods
|
2548
2504
|
function $deny_frozen_access(obj) {
|
2549
2505
|
if (obj.$$frozen) {
|
2550
|
-
$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]]));
|
2551
2507
|
}
|
2552
2508
|
};
|
2553
2509
|
Opal.deny_frozen_access = $deny_frozen_access;
|
@@ -2672,7 +2628,7 @@
|
|
2672
2628
|
if (part.ignoreCase !== ignoreCase)
|
2673
2629
|
Opal.Kernel.$warn(
|
2674
2630
|
"ignore case doesn't match for " + part.source.$inspect(),
|
2675
|
-
|
2631
|
+
new Map([['uplevel', 1]])
|
2676
2632
|
)
|
2677
2633
|
|
2678
2634
|
part = part.source;
|
@@ -2923,7 +2879,7 @@
|
|
2923
2879
|
// Primitives for handling parameters
|
2924
2880
|
Opal.ensure_kwargs = function(kwargs) {
|
2925
2881
|
if (kwargs == null) {
|
2926
|
-
return
|
2882
|
+
return new Map();
|
2927
2883
|
} else if (kwargs.$$is_hash) {
|
2928
2884
|
return kwargs;
|
2929
2885
|
} else {
|
@@ -2932,10 +2888,11 @@
|
|
2932
2888
|
}
|
2933
2889
|
|
2934
2890
|
Opal.get_kwarg = function(kwargs, key) {
|
2935
|
-
|
2891
|
+
var kwarg = Opal.hash_get(kwargs, key);
|
2892
|
+
if (kwarg === undefined) {
|
2936
2893
|
$raise(Opal.ArgumentError, 'missing keyword: '+key);
|
2937
2894
|
}
|
2938
|
-
return
|
2895
|
+
return kwarg;
|
2939
2896
|
}
|
2940
2897
|
|
2941
2898
|
// Arrays of size > 32 elements that contain only strings,
|
@@ -3020,10 +2977,9 @@
|
|
3020
2977
|
|
3021
2978
|
// Foward calls to define_method on the top object to Object
|
3022
2979
|
function top_define_method() {
|
3023
|
-
var args = $slice(arguments);
|
3024
2980
|
var block = top_define_method.$$p;
|
3025
2981
|
top_define_method.$$p = null;
|
3026
|
-
return Opal.send(_Object, 'define_method',
|
2982
|
+
return Opal.send(_Object, 'define_method', arguments, block)
|
3027
2983
|
};
|
3028
2984
|
|
3029
2985
|
// Nil
|
@@ -3037,7 +2993,7 @@
|
|
3037
2993
|
Object.seal(nil);
|
3038
2994
|
|
3039
2995
|
Opal.thrower = function(type) {
|
3040
|
-
var thrower =
|
2996
|
+
var thrower = { message: 'unexpected '+type };
|
3041
2997
|
thrower.$thrower_type = type;
|
3042
2998
|
thrower.$throw = function(value) {
|
3043
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
|