opal 1.4.1 → 1.5.0.rc1
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/.eslintrc.js +5 -3
- data/.rubocop.yml +1 -0
- data/UNRELEASED.md +37 -2
- data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
- data/docs/releasing.md +10 -2
- data/lib/opal/ast/matcher.rb +77 -0
- data/lib/opal/cache.rb +1 -1
- data/lib/opal/cli_runners/applescript.rb +2 -0
- data/lib/opal/compiler.rb +18 -9
- data/lib/opal/nodes/call.rb +73 -28
- data/lib/opal/nodes/def.rb +31 -27
- data/lib/opal/nodes/definitions.rb +2 -0
- data/lib/opal/nodes/helpers.rb +4 -23
- data/lib/opal/nodes/if.rb +222 -0
- data/lib/opal/nodes/iter.rb +41 -37
- data/lib/opal/nodes/literal.rb +2 -2
- data/lib/opal/nodes/masgn.rb +15 -17
- data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
- data/lib/opal/nodes/node_with_args.rb +1 -0
- data/lib/opal/nodes/top.rb +26 -10
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/default_config.rb +3 -2
- data/lib/opal/repl.rb +1 -1
- data/lib/opal/rewriter.rb +13 -6
- data/lib/opal/rewriters/base.rb +12 -1
- data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +23 -28
- data/opal/corelib/binding.rb +14 -4
- data/opal/corelib/constants.rb +3 -3
- data/opal/corelib/hash.rb +2 -2
- data/opal/corelib/irb.rb +192 -0
- data/opal/corelib/math/polyfills.rb +127 -0
- data/opal/corelib/math.rb +14 -194
- data/opal/corelib/module.rb +23 -25
- data/opal/corelib/number.rb +63 -14
- data/opal/corelib/regexp.rb +2 -0
- data/opal/corelib/runtime.js +56 -20
- data/opal/corelib/string.rb +38 -59
- data/opal/corelib/time.rb +106 -68
- data/opal/opal/full.rb +0 -1
- data/opal/opal.rb +4 -1
- data/spec/filters/bugs/date.rb +0 -3
- data/spec/filters/bugs/datetime.rb +65 -0
- data/spec/filters/bugs/float.rb +0 -18
- data/spec/filters/bugs/hash.rb +0 -2
- data/spec/filters/bugs/language.rb +0 -3
- data/spec/filters/bugs/marshal.rb +0 -1
- data/spec/filters/bugs/string.rb +0 -30
- data/spec/filters/bugs/time.rb +18 -8
- data/spec/lib/cli_spec.rb +2 -2
- data/spec/lib/compiler_spec.rb +8 -8
- data/spec/lib/rewriters/base_spec.rb +1 -1
- data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
- data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
- data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
- data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
- data/spec/lib/rewriters/forward_args_spec.rb +2 -3
- data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
- data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
- data/spec/lib/rewriters/numblocks_spec.rb +3 -5
- data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
- data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
- data/spec/opal/compiler/irb_spec.rb +4 -0
- data/spec/opal/core/language/super_spec.rb +26 -0
- data/spec/opal/core/regexp/assertions_spec.rb +19 -0
- data/spec/opal/core/string/to_proc_spec.rb +19 -0
- data/spec/ruby_specs +4 -0
- data/spec/support/rewriters_helper.rb +43 -23
- data/stdlib/date/date_time.rb +71 -0
- data/stdlib/date/formatters.rb +28 -0
- data/stdlib/date/infinity.rb +73 -0
- data/stdlib/date.rb +77 -214
- data/stdlib/opal/repl_js.rb +1 -1
- data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
- data/stdlib/time.rb +39 -2
- data/stdlib/uri.rb +53 -0
- data/tasks/performance/asciidoctor_test.rb.erb +3 -1
- data/tasks/performance/optimization_status.rb +3 -2
- data/tasks/performance.rake +69 -35
- data/tasks/testing.rake +1 -0
- data/test/opal/test_uri.rb +35 -0
- data/yarn.lock +27 -5
- metadata +31 -18
- data/lib/opal/nodes/csend.rb +0 -24
- data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
- data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
- data/stdlib/nodejs/irb.rb +0 -43
data/opal/corelib/string.rb
CHANGED
@@ -8,15 +8,6 @@ class ::String < `String`
|
|
8
8
|
|
9
9
|
%x{
|
10
10
|
Opal.prop(#{self}.$$prototype, '$$is_string', true);
|
11
|
-
|
12
|
-
Opal.prop(#{self}.$$prototype, '$$cast', function(string) {
|
13
|
-
var klass = this.$$class;
|
14
|
-
if (klass.$$constructor === String) {
|
15
|
-
return string;
|
16
|
-
} else {
|
17
|
-
return new klass.$$constructor(string);
|
18
|
-
}
|
19
|
-
});
|
20
11
|
}
|
21
12
|
|
22
13
|
def __id__
|
@@ -66,7 +57,7 @@ class ::String < `String`
|
|
66
57
|
}
|
67
58
|
|
68
59
|
if (count === 0) {
|
69
|
-
return
|
60
|
+
return '';
|
70
61
|
}
|
71
62
|
|
72
63
|
var result = '',
|
@@ -91,7 +82,7 @@ class ::String < `String`
|
|
91
82
|
string += string;
|
92
83
|
}
|
93
84
|
|
94
|
-
return
|
85
|
+
return result;
|
95
86
|
}
|
96
87
|
end
|
97
88
|
|
@@ -181,7 +172,7 @@ class ::String < `String`
|
|
181
172
|
length = 0;
|
182
173
|
}
|
183
174
|
|
184
|
-
return self
|
175
|
+
return self.substr(index, length);
|
185
176
|
}
|
186
177
|
|
187
178
|
|
@@ -189,7 +180,7 @@ class ::String < `String`
|
|
189
180
|
if (length != null) {
|
190
181
|
#{::Kernel.raise ::TypeError}
|
191
182
|
}
|
192
|
-
return self.indexOf(index) !== -1 ?
|
183
|
+
return self.indexOf(index) !== -1 ? index : nil;
|
193
184
|
}
|
194
185
|
|
195
186
|
|
@@ -204,17 +195,17 @@ class ::String < `String`
|
|
204
195
|
#{$~ = ::MatchData.new(`index`, `match`)}
|
205
196
|
|
206
197
|
if (length == null) {
|
207
|
-
return
|
198
|
+
return match[0];
|
208
199
|
}
|
209
200
|
|
210
201
|
length = $coerce_to(length, #{::Integer}, 'to_int');
|
211
202
|
|
212
203
|
if (length < 0 && -length < match.length) {
|
213
|
-
return
|
204
|
+
return match[length += match.length];
|
214
205
|
}
|
215
206
|
|
216
207
|
if (length >= 0 && length < match.length) {
|
217
|
-
return
|
208
|
+
return match[length];
|
218
209
|
}
|
219
210
|
|
220
211
|
return nil;
|
@@ -231,7 +222,7 @@ class ::String < `String`
|
|
231
222
|
if (index >= size || index < 0) {
|
232
223
|
return nil;
|
233
224
|
}
|
234
|
-
return self
|
225
|
+
return self.substr(index, 1);
|
235
226
|
}
|
236
227
|
|
237
228
|
length = $coerce_to(length, #{::Integer}, 'to_int');
|
@@ -244,7 +235,7 @@ class ::String < `String`
|
|
244
235
|
return nil;
|
245
236
|
}
|
246
237
|
|
247
|
-
return self
|
238
|
+
return self.substr(index, length);
|
248
239
|
}
|
249
240
|
end
|
250
241
|
|
@@ -253,7 +244,7 @@ class ::String < `String`
|
|
253
244
|
end
|
254
245
|
|
255
246
|
def capitalize
|
256
|
-
`self
|
247
|
+
`self.charAt(0).toUpperCase() + self.substr(1).toLowerCase()`
|
257
248
|
end
|
258
249
|
|
259
250
|
def casecmp(other)
|
@@ -294,7 +285,7 @@ class ::String < `String`
|
|
294
285
|
var ljustified = #{ljust ((width + `self.length`) / 2).ceil, padstr},
|
295
286
|
rjustified = #{rjust ((width + `self.length`) / 2).floor, padstr};
|
296
287
|
|
297
|
-
return
|
288
|
+
return rjustified + ljustified.slice(self.length);
|
298
289
|
}
|
299
290
|
end
|
300
291
|
|
@@ -321,7 +312,7 @@ class ::String < `String`
|
|
321
312
|
}
|
322
313
|
|
323
314
|
if (result != null) {
|
324
|
-
return
|
315
|
+
return result;
|
325
316
|
}
|
326
317
|
}
|
327
318
|
|
@@ -340,7 +331,7 @@ class ::String < `String`
|
|
340
331
|
result = self.substr(0, length - 1);
|
341
332
|
}
|
342
333
|
|
343
|
-
return
|
334
|
+
return result;
|
344
335
|
}
|
345
336
|
end
|
346
337
|
|
@@ -383,7 +374,7 @@ class ::String < `String`
|
|
383
374
|
if (char_class === null) {
|
384
375
|
return self;
|
385
376
|
}
|
386
|
-
return self
|
377
|
+
return self.replace(new RegExp(char_class, 'g'), '');
|
387
378
|
}
|
388
379
|
end
|
389
380
|
|
@@ -394,7 +385,7 @@ class ::String < `String`
|
|
394
385
|
}
|
395
386
|
|
396
387
|
if (self.slice(0, prefix.length) === prefix) {
|
397
|
-
return self
|
388
|
+
return self.slice(prefix.length);
|
398
389
|
} else {
|
399
390
|
return self;
|
400
391
|
}
|
@@ -408,7 +399,7 @@ class ::String < `String`
|
|
408
399
|
}
|
409
400
|
|
410
401
|
if (self.slice(self.length - suffix.length) === suffix) {
|
411
|
-
return self
|
402
|
+
return self.slice(0, self.length - suffix.length);
|
412
403
|
} else {
|
413
404
|
return self;
|
414
405
|
}
|
@@ -416,7 +407,7 @@ class ::String < `String`
|
|
416
407
|
end
|
417
408
|
|
418
409
|
def downcase
|
419
|
-
`self
|
410
|
+
`self.toLowerCase()`
|
420
411
|
end
|
421
412
|
|
422
413
|
def each_line(separator = $/, chomp: false, &block)
|
@@ -555,7 +546,7 @@ class ::String < `String`
|
|
555
546
|
}
|
556
547
|
|
557
548
|
#{$~ = `match_data`}
|
558
|
-
return
|
549
|
+
return result;
|
559
550
|
}
|
560
551
|
end
|
561
552
|
|
@@ -682,7 +673,7 @@ class ::String < `String`
|
|
682
673
|
result += padstr;
|
683
674
|
}
|
684
675
|
|
685
|
-
return self
|
676
|
+
return self + result.slice(0, width);
|
686
677
|
}
|
687
678
|
end
|
688
679
|
|
@@ -726,7 +717,7 @@ class ::String < `String`
|
|
726
717
|
%x{
|
727
718
|
var i = self.length;
|
728
719
|
if (i === 0) {
|
729
|
-
return
|
720
|
+
return '';
|
730
721
|
}
|
731
722
|
var result = self;
|
732
723
|
var first_alphanum_char_index = self.search(/[a-zA-Z0-9]/);
|
@@ -788,7 +779,7 @@ class ::String < `String`
|
|
788
779
|
break;
|
789
780
|
}
|
790
781
|
}
|
791
|
-
return
|
782
|
+
return result;
|
792
783
|
}
|
793
784
|
end
|
794
785
|
|
@@ -939,7 +930,7 @@ class ::String < `String`
|
|
939
930
|
result = Array(patterns + 1).join(padstr),
|
940
931
|
remaining = chars - result.length;
|
941
932
|
|
942
|
-
return
|
933
|
+
return result + padstr.slice(0, remaining) + self;
|
943
934
|
}
|
944
935
|
end
|
945
936
|
|
@@ -1069,24 +1060,17 @@ class ::String < `String`
|
|
1069
1060
|
result = string.split(pattern);
|
1070
1061
|
|
1071
1062
|
if (result.length === 1 && result[0] === string) {
|
1072
|
-
return [
|
1063
|
+
return [result[0]];
|
1073
1064
|
}
|
1074
1065
|
|
1075
1066
|
while ((i = result.indexOf(undefined)) !== -1) {
|
1076
1067
|
result.splice(i, 1);
|
1077
1068
|
}
|
1078
1069
|
|
1079
|
-
function castResult() {
|
1080
|
-
for (i = 0; i < result.length; i++) {
|
1081
|
-
result[i] = self.$$cast(result[i]);
|
1082
|
-
}
|
1083
|
-
}
|
1084
|
-
|
1085
1070
|
if (limit === 0) {
|
1086
1071
|
while (result[result.length - 1] === '') {
|
1087
1072
|
result.length -= 1;
|
1088
1073
|
}
|
1089
|
-
castResult();
|
1090
1074
|
return result;
|
1091
1075
|
}
|
1092
1076
|
|
@@ -1098,18 +1082,15 @@ class ::String < `String`
|
|
1098
1082
|
result.push('');
|
1099
1083
|
}
|
1100
1084
|
}
|
1101
|
-
castResult();
|
1102
1085
|
return result;
|
1103
1086
|
}
|
1104
1087
|
|
1105
1088
|
if (match !== null && match[0] === '') {
|
1106
1089
|
result.splice(limit - 1, result.length - 1, result.slice(limit - 1).join(''));
|
1107
|
-
castResult();
|
1108
1090
|
return result;
|
1109
1091
|
}
|
1110
1092
|
|
1111
1093
|
if (limit >= result.length) {
|
1112
|
-
castResult();
|
1113
1094
|
return result;
|
1114
1095
|
}
|
1115
1096
|
|
@@ -1123,7 +1104,6 @@ class ::String < `String`
|
|
1123
1104
|
match = pattern.exec(string);
|
1124
1105
|
}
|
1125
1106
|
result.splice(limit - 1, result.length - 1, string.slice(index));
|
1126
|
-
castResult();
|
1127
1107
|
return result;
|
1128
1108
|
}
|
1129
1109
|
end
|
@@ -1131,13 +1111,13 @@ class ::String < `String`
|
|
1131
1111
|
def squeeze(*sets)
|
1132
1112
|
%x{
|
1133
1113
|
if (sets.length === 0) {
|
1134
|
-
return self
|
1114
|
+
return self.replace(/(.)\1+/g, '$1');
|
1135
1115
|
}
|
1136
1116
|
var char_class = char_class_from_char_sets(sets);
|
1137
1117
|
if (char_class === null) {
|
1138
1118
|
return self;
|
1139
1119
|
}
|
1140
|
-
return self
|
1120
|
+
return self.replace(new RegExp('(' + char_class + ')\\1+', 'g'), '$1');
|
1141
1121
|
}
|
1142
1122
|
end
|
1143
1123
|
|
@@ -1224,7 +1204,7 @@ class ::String < `String`
|
|
1224
1204
|
}
|
1225
1205
|
}
|
1226
1206
|
|
1227
|
-
return
|
1207
|
+
return result;
|
1228
1208
|
}
|
1229
1209
|
end
|
1230
1210
|
|
@@ -1254,11 +1234,7 @@ class ::String < `String`
|
|
1254
1234
|
return $1 ? $0.toUpperCase() : $0.toLowerCase();
|
1255
1235
|
});
|
1256
1236
|
|
1257
|
-
|
1258
|
-
return str;
|
1259
|
-
}
|
1260
|
-
|
1261
|
-
return #{self.class.new `str`};
|
1237
|
+
return str;
|
1262
1238
|
}
|
1263
1239
|
end
|
1264
1240
|
|
@@ -1339,7 +1315,7 @@ class ::String < `String`
|
|
1339
1315
|
end
|
1340
1316
|
|
1341
1317
|
def to_proc
|
1342
|
-
method_name =
|
1318
|
+
method_name = `self.valueOf()`
|
1343
1319
|
|
1344
1320
|
::Kernel.proc do |*args, &block|
|
1345
1321
|
%x{
|
@@ -1351,20 +1327,23 @@ class ::String < `String`
|
|
1351
1327
|
|
1352
1328
|
if (recv == null) recv = nil;
|
1353
1329
|
|
1354
|
-
var body = recv[#{method_name}];
|
1330
|
+
var body = recv['$' + #{method_name}];
|
1355
1331
|
|
1356
1332
|
if (!body) {
|
1357
|
-
|
1333
|
+
body = recv.$method_missing;
|
1334
|
+
args[0] = #{method_name};
|
1335
|
+
} else {
|
1336
|
+
args = args.slice(1);
|
1358
1337
|
}
|
1359
1338
|
|
1360
1339
|
if (typeof block === 'function') {
|
1361
1340
|
body.$$p = block;
|
1362
1341
|
}
|
1363
1342
|
|
1364
|
-
if (args.length ===
|
1343
|
+
if (args.length === 0) {
|
1365
1344
|
return body.call(recv);
|
1366
1345
|
} else {
|
1367
|
-
return body.apply(recv, args
|
1346
|
+
return body.apply(recv, args);
|
1368
1347
|
}
|
1369
1348
|
}
|
1370
1349
|
end
|
@@ -1515,7 +1494,7 @@ class ::String < `String`
|
|
1515
1494
|
new_str += (sub != null ? sub : ch);
|
1516
1495
|
}
|
1517
1496
|
}
|
1518
|
-
return
|
1497
|
+
return new_str;
|
1519
1498
|
}
|
1520
1499
|
end
|
1521
1500
|
|
@@ -1678,12 +1657,12 @@ class ::String < `String`
|
|
1678
1657
|
}
|
1679
1658
|
}
|
1680
1659
|
}
|
1681
|
-
return
|
1660
|
+
return new_str;
|
1682
1661
|
}
|
1683
1662
|
end
|
1684
1663
|
|
1685
1664
|
def upcase
|
1686
|
-
`self
|
1665
|
+
`self.toUpperCase()`
|
1687
1666
|
end
|
1688
1667
|
|
1689
1668
|
def upto(stop, excl = false, &block)
|
data/opal/corelib/time.rb
CHANGED
@@ -21,7 +21,7 @@ class ::Time < `Date`
|
|
21
21
|
#{::Kernel.raise ::TypeError, "can't convert Time into an exact number"}
|
22
22
|
}
|
23
23
|
result = new Date(seconds.getTime());
|
24
|
-
result.
|
24
|
+
result.timezone = seconds.timezone;
|
25
25
|
return result;
|
26
26
|
}
|
27
27
|
|
@@ -135,16 +135,12 @@ class ::Time < `Date`
|
|
135
135
|
|
136
136
|
def self.new(year = undefined, month = nil, day = nil, hour = nil, min = nil, sec = nil, utc_offset = nil)
|
137
137
|
%x{
|
138
|
-
var args, result;
|
138
|
+
var args, result, timezone;
|
139
139
|
|
140
140
|
if (year === undefined) {
|
141
141
|
return new Date();
|
142
142
|
}
|
143
143
|
|
144
|
-
if (utc_offset !== nil) {
|
145
|
-
#{::Kernel.raise ::ArgumentError, 'Opal does not support explicitly specifying UTC offset for Time'}
|
146
|
-
}
|
147
|
-
|
148
144
|
args = time_params(year, month, day, hour, min, sec);
|
149
145
|
year = args[0];
|
150
146
|
month = args[1];
|
@@ -157,10 +153,51 @@ class ::Time < `Date`
|
|
157
153
|
if (year < 100) {
|
158
154
|
result.setFullYear(year);
|
159
155
|
}
|
156
|
+
|
157
|
+
if (utc_offset !== nil) {
|
158
|
+
timezone = #{_parse_offset(utc_offset)};
|
159
|
+
}
|
160
|
+
|
161
|
+
if (timezone != null) {
|
162
|
+
result = new Date(result.getTime() - timezone * 3600000 - result.getTimezoneOffset() * 60000);
|
163
|
+
result.timezone = timezone;
|
164
|
+
}
|
165
|
+
|
160
166
|
return result;
|
161
167
|
}
|
162
168
|
end
|
163
169
|
|
170
|
+
# @private
|
171
|
+
def self._parse_offset(utc_offset)
|
172
|
+
%x{
|
173
|
+
var timezone;
|
174
|
+
if (utc_offset.$$is_string) {
|
175
|
+
if (utc_offset == 'UTC') {
|
176
|
+
timezone = 0;
|
177
|
+
}
|
178
|
+
else if(/^[+-]\d\d:[0-5]\d$/.test(utc_offset)) {
|
179
|
+
var sign, hours, minutes;
|
180
|
+
sign = utc_offset[0];
|
181
|
+
hours = +(utc_offset[1] + utc_offset[2]);
|
182
|
+
minutes = +(utc_offset[4] + utc_offset[5]);
|
183
|
+
|
184
|
+
timezone = (sign == '-' ? -1 : 1) * (hours + minutes / 60);
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
// Unsupported: "A".."I","K".."Z"
|
188
|
+
#{::Kernel.raise ::ArgumentError, %'"+HH:MM", "-HH:MM", "UTC" expected for utc_offset: #{utc_offset}'}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
else if (utc_offset.$$is_number) {
|
192
|
+
timezone = utc_offset / 3600;
|
193
|
+
}
|
194
|
+
else {
|
195
|
+
#{::Kernel.raise ::ArgumentError, "Opal doesn't support other types for a timezone argument than Integer and String"}
|
196
|
+
}
|
197
|
+
return timezone;
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
164
201
|
def self.local(year, month = nil, day = nil, hour = nil, min = nil, sec = nil, millisecond = nil, _dummy1 = nil, _dummy2 = nil, _dummy3 = nil)
|
165
202
|
# The _dummy args are there only because the MRI version accepts up to 10 arguments
|
166
203
|
%x{
|
@@ -219,7 +256,7 @@ class ::Time < `Date`
|
|
219
256
|
if (year < 100) {
|
220
257
|
result.setUTCFullYear(year);
|
221
258
|
}
|
222
|
-
result.
|
259
|
+
result.timezone = 0;
|
223
260
|
return result;
|
224
261
|
}
|
225
262
|
end
|
@@ -238,7 +275,7 @@ class ::Time < `Date`
|
|
238
275
|
other = #{::Opal.coerce_to!(other, ::Integer, :to_int)};
|
239
276
|
}
|
240
277
|
var result = new Date(self.getTime() + (other * 1000));
|
241
|
-
result.
|
278
|
+
result.timezone = self.timezone;
|
242
279
|
return result;
|
243
280
|
}
|
244
281
|
end
|
@@ -253,7 +290,7 @@ class ::Time < `Date`
|
|
253
290
|
other = #{::Opal.coerce_to!(other, ::Integer, :to_int)};
|
254
291
|
}
|
255
292
|
var result = new Date(self.getTime() - (other * 1000));
|
256
|
-
result.
|
293
|
+
result.timezone = self.timezone;
|
257
294
|
return result;
|
258
295
|
}
|
259
296
|
end
|
@@ -283,8 +320,22 @@ class ::Time < `Date`
|
|
283
320
|
strftime '%a %b %e %H:%M:%S %Y'
|
284
321
|
end
|
285
322
|
|
286
|
-
|
287
|
-
|
323
|
+
[
|
324
|
+
[:year, 'getFullYear', 'getUTCFullYear'],
|
325
|
+
[:mon, 'getMonth', 'getUTCMonth', 1],
|
326
|
+
[:wday, 'getDay', 'getUTCDay'],
|
327
|
+
[:day, 'getDate', 'getUTCDate'],
|
328
|
+
[:hour, 'getHours', 'getUTCHours'],
|
329
|
+
[:min, 'getMinutes', 'getUTCMinutes'],
|
330
|
+
[:sec, 'getSeconds', 'getUTCSeconds'],
|
331
|
+
].each do |method, getter, utcgetter, difference = 0|
|
332
|
+
define_method method do
|
333
|
+
%x{
|
334
|
+
return difference + ((self.timezone != null) ?
|
335
|
+
(new Date(self.getTime() + self.timezone * 3600000))[utcgetter]() :
|
336
|
+
self[getter]())
|
337
|
+
}
|
338
|
+
end
|
288
339
|
end
|
289
340
|
|
290
341
|
def yday
|
@@ -319,18 +370,24 @@ class ::Time < `Date`
|
|
319
370
|
other.is_a?(::Time) && (self <=> other).zero?
|
320
371
|
end
|
321
372
|
|
322
|
-
|
323
|
-
|
373
|
+
[
|
374
|
+
[:sunday?, 0],
|
375
|
+
[:monday?, 1],
|
376
|
+
[:tuesday?, 2],
|
377
|
+
[:wednesday?, 3],
|
378
|
+
[:thursday?, 4],
|
379
|
+
[:friday?, 5],
|
380
|
+
[:saturday?, 6]
|
381
|
+
].each do |method, weekday|
|
382
|
+
define_method method do
|
383
|
+
`#{wday} === weekday`
|
384
|
+
end
|
324
385
|
end
|
325
386
|
|
326
387
|
def hash
|
327
388
|
`'Time:' + self.getTime()`
|
328
389
|
end
|
329
390
|
|
330
|
-
def hour
|
331
|
-
`self.is_utc ? self.getUTCHours() : self.getHours()`
|
332
|
-
end
|
333
|
-
|
334
391
|
def inspect
|
335
392
|
if utc?
|
336
393
|
strftime '%Y-%m-%d %H:%M:%S UTC'
|
@@ -339,30 +396,10 @@ class ::Time < `Date`
|
|
339
396
|
end
|
340
397
|
end
|
341
398
|
|
342
|
-
def min
|
343
|
-
`self.is_utc ? self.getUTCMinutes() : self.getMinutes()`
|
344
|
-
end
|
345
|
-
|
346
|
-
def mon
|
347
|
-
`(self.is_utc ? self.getUTCMonth() : self.getMonth()) + 1`
|
348
|
-
end
|
349
|
-
|
350
|
-
def monday?
|
351
|
-
`#{wday} == 1`
|
352
|
-
end
|
353
|
-
|
354
|
-
def saturday?
|
355
|
-
`#{wday} == 6`
|
356
|
-
end
|
357
|
-
|
358
|
-
def sec
|
359
|
-
`self.is_utc ? self.getUTCSeconds() : self.getSeconds()`
|
360
|
-
end
|
361
|
-
|
362
399
|
def succ
|
363
400
|
%x{
|
364
401
|
var result = new Date(self.getTime() + 1000);
|
365
|
-
result.
|
402
|
+
result.timezone = self.timezone;
|
366
403
|
return result;
|
367
404
|
}
|
368
405
|
end
|
@@ -373,6 +410,9 @@ class ::Time < `Date`
|
|
373
410
|
|
374
411
|
def zone
|
375
412
|
%x{
|
413
|
+
if (self.timezone === 0) return "UTC";
|
414
|
+
else if (self.timezone != null) return nil;
|
415
|
+
|
376
416
|
var string = self.toString(),
|
377
417
|
result;
|
378
418
|
|
@@ -395,30 +435,30 @@ class ::Time < `Date`
|
|
395
435
|
def getgm
|
396
436
|
%x{
|
397
437
|
var result = new Date(self.getTime());
|
398
|
-
result.
|
438
|
+
result.timezone = 0;
|
399
439
|
return result;
|
400
440
|
}
|
401
441
|
end
|
402
442
|
|
403
443
|
def gmtime
|
404
444
|
%x{
|
405
|
-
self.
|
445
|
+
self.timezone = 0;
|
406
446
|
return self;
|
407
447
|
}
|
408
448
|
end
|
409
449
|
|
410
450
|
def gmt?
|
411
|
-
`self.
|
451
|
+
`self.timezone === 0`
|
412
452
|
end
|
413
453
|
|
414
454
|
def gmt_offset
|
415
|
-
`self.
|
455
|
+
`(self.timezone != null) ? self.timezone * 60 : -self.getTimezoneOffset() * 60`
|
416
456
|
end
|
417
457
|
|
418
458
|
def strftime(format)
|
419
459
|
%x{
|
420
460
|
return format.replace(/%([\-_#^0]*:{0,2})(\d+)?([EO]*)(.)/g, function(full, flags, width, _, conv) {
|
421
|
-
var result = "",
|
461
|
+
var result = "", jd, c, s,
|
422
462
|
zero = flags.indexOf('0') !== -1,
|
423
463
|
pad = flags.indexOf('-') === -1,
|
424
464
|
blank = flags.indexOf('_') !== -1,
|
@@ -534,7 +574,7 @@ class ::Time < `Date`
|
|
534
574
|
break;
|
535
575
|
|
536
576
|
case 'z':
|
537
|
-
var offset = self.getTimezoneOffset(),
|
577
|
+
var offset = (self.timezone == null) ? self.getTimezoneOffset() : (-self.timezone * 60),
|
538
578
|
hours = Math.floor(Math.abs(offset) / 60),
|
539
579
|
minutes = Math.abs(offset) % 60;
|
540
580
|
|
@@ -633,6 +673,28 @@ class ::Time < `Date`
|
|
633
673
|
result += #{strftime('%H:%M:%S')};
|
634
674
|
break;
|
635
675
|
|
676
|
+
// Non-standard: JIS X 0301 date format
|
677
|
+
case 'J':
|
678
|
+
jd = #{to_date.jd};
|
679
|
+
if (jd < 2405160) {
|
680
|
+
result += #{strftime('%Y-%m-%d')};
|
681
|
+
break;
|
682
|
+
}
|
683
|
+
else if (jd < 2419614)
|
684
|
+
c = 'M', s = 1867;
|
685
|
+
else if (jd < 2424875)
|
686
|
+
c = 'T', s = 1911;
|
687
|
+
else if (jd < 2447535)
|
688
|
+
c = 'S', s = 1925;
|
689
|
+
else if (jd < 2458605)
|
690
|
+
c = 'H', s = 1988;
|
691
|
+
else
|
692
|
+
c = 'R', s = 2018;
|
693
|
+
|
694
|
+
result += #{format '%c%02d', `c`, year - `s`};
|
695
|
+
result += #{strftime('-%m-%d')};
|
696
|
+
break;
|
697
|
+
|
636
698
|
default:
|
637
699
|
return full;
|
638
700
|
}
|
@@ -655,14 +717,6 @@ class ::Time < `Date`
|
|
655
717
|
}
|
656
718
|
end
|
657
719
|
|
658
|
-
def sunday?
|
659
|
-
`#{wday} == 0`
|
660
|
-
end
|
661
|
-
|
662
|
-
def thursday?
|
663
|
-
`#{wday} == 4`
|
664
|
-
end
|
665
|
-
|
666
720
|
def to_a
|
667
721
|
[sec, min, hour, day, month, year, wday, yday, isdst, zone]
|
668
722
|
end
|
@@ -675,22 +729,6 @@ class ::Time < `Date`
|
|
675
729
|
`parseInt(self.getTime() / 1000, 10)`
|
676
730
|
end
|
677
731
|
|
678
|
-
def tuesday?
|
679
|
-
`#{wday} == 2`
|
680
|
-
end
|
681
|
-
|
682
|
-
def wday
|
683
|
-
`self.is_utc ? self.getUTCDay() : self.getDay()`
|
684
|
-
end
|
685
|
-
|
686
|
-
def wednesday?
|
687
|
-
`#{wday} == 3`
|
688
|
-
end
|
689
|
-
|
690
|
-
def year
|
691
|
-
`self.is_utc ? self.getUTCFullYear() : self.getFullYear()`
|
692
|
-
end
|
693
|
-
|
694
732
|
def cweek_cyear
|
695
733
|
jan01 = ::Time.new(year, 1, 1)
|
696
734
|
jan01_wday = jan01.wday
|
data/opal/opal/full.rb
CHANGED
data/opal/opal.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
::Object.autoload :Rational, 'corelib/rational'
|
11
11
|
::Object.require 'corelib/time'
|
12
12
|
::Object.autoload :Struct, 'corelib/struct'
|
13
|
-
::Object.
|
13
|
+
::Object.autoload :Dir, 'corelib/dir'
|
14
14
|
::Object.autoload :File, 'corelib/file'
|
15
15
|
|
16
16
|
::Object.require 'corelib/process/base'
|
@@ -18,3 +18,6 @@
|
|
18
18
|
::Object.autoload :Random, 'corelib/random'
|
19
19
|
|
20
20
|
::Object.require 'corelib/unsupported'
|
21
|
+
|
22
|
+
::Object.require 'corelib/binding'
|
23
|
+
::Object.require 'corelib/irb'
|
data/spec/filters/bugs/date.rb
CHANGED
@@ -20,9 +20,7 @@ opal_filter "Date" do
|
|
20
20
|
fails "Date#julian converts a date object into another with the Julian calendar"
|
21
21
|
fails "Date#julian? marks a day before the calendar reform as Julian"
|
22
22
|
fails "Date#ld determines the Modified Julian day"
|
23
|
-
fails "Date#mday determines the day of the month"
|
24
23
|
fails "Date#mjd determines the Modified Julian day"
|
25
|
-
fails "Date#mon determines the month"
|
26
24
|
fails "Date#new_start converts a date object into another with a new calendar reform"
|
27
25
|
fails "Date#parse coerces using to_str" # ArgumentError: invalid date
|
28
26
|
fails "Date#parse parses a day name into a Date object"
|
@@ -72,7 +70,6 @@ opal_filter "Date" do
|
|
72
70
|
fails "Date#valid_date? handles negative months and days"
|
73
71
|
fails "Date#valid_date? returns false if it is not a valid civil date"
|
74
72
|
fails "Date#valid_date? returns true if it is a valid civil date"
|
75
|
-
fails "Date#yday determines the year"
|
76
73
|
fails "Date._iso8601 returns an empty hash if the argument is a invalid Date" # NoMethodError: undefined method `_iso8601' for Date
|
77
74
|
fails "Date._rfc3339 returns an empty hash if the argument is a invalid Date" # NoMethodError: undefined method `_rfc3339' for Date
|
78
75
|
fails "Date.iso8601 parses YYYY-MM-DD into a Date object" # NoMethodError: undefined method `iso8601' for Date
|