Skip to content

Commit 91e4173

Browse files
committed
#19: array (feat): CommentArray::sort, untested
array (patch): fixes a bug that CommentArray::reverse could not clean the mess
1 parent 61ba0a9 commit 91e4173

File tree

4 files changed

+102
-26
lines changed

4 files changed

+102
-26
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"typescript": "^4.0.3"
6060
},
6161
"dependencies": {
62+
"array-timsort": "^1.0.3",
6263
"core-util-is": "^1.0.2",
6364
"esprima": "^4.0.1",
6465
"has-own-prop": "^2.0.0",

src/array.js

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
1-
const hasOwnProperty = require('has-own-prop')
21
const {isArray} = require('core-util-is')
2+
const {sort} = require('array-timsort')
33

44
const {
55
SYMBOL_PREFIXES,
66

77
UNDEFINED,
88

99
symbol,
10-
define,
11-
copy_comments,
12-
copy_all_comments
10+
copy_all_comments,
11+
swap_comments
1312
} = require('./common')
1413

1514

16-
const swap_comments = (array, from, to) => {
17-
if (from === to) {
18-
return
19-
}
20-
21-
SYMBOL_PREFIXES.forEach(prefix => {
22-
const target_prop = symbol(prefix, to)
23-
if (!hasOwnProperty(array, target_prop)) {
24-
copy_comments(array, array, to, from, prefix)
25-
return
26-
}
27-
28-
const comments = array[target_prop]
29-
copy_comments(array, array, to, from, prefix)
30-
define(array, symbol(prefix, from), comments)
31-
})
32-
}
33-
3415
const reverse_comments = array => {
3516
const {length} = array
3617
let i = 0
@@ -235,6 +216,43 @@ class CommentArray extends Array {
235216

236217
return ret
237218
}
219+
220+
sort (...args) {
221+
const result = sort(
222+
this,
223+
// Make sure there is no more than one argument
224+
...args.slice(0, 1)
225+
)
226+
227+
// For example,
228+
// if we sort ['c', 'a', 'b', 'd'],
229+
// then `result` will be [1, 2, 0, 3], and the array is ['a', 'b', 'c', 'd']
230+
231+
// First, we swap index 0 and index 1, then the array comments are
232+
// ['a.comments', 'c.comments', 'b.comments', 'd.comments']
233+
234+
// Then swap index 1 and index 2
235+
// ['a.comments', 'b.comments', 'c.comments', 'd.comments']
236+
237+
// And we should not swap index 2 and index 0
238+
239+
const sorted = new Set()
240+
241+
result.forEach((new_index, original_index) => {
242+
if (new_index === original_index) {
243+
return
244+
}
245+
246+
if (sorted.has(new_index) && sorted.has(original_index)) {
247+
return
248+
}
249+
250+
sorted.add(new_index)
251+
sorted.add(original_index)
252+
253+
swap_comments(this, new_index, original_index)
254+
})
255+
}
238256
}
239257

240258
module.exports = {

src/common.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ const copy_all_comments = (
7272
})
7373
}
7474

75+
const swap_comments = (array, from, to) => {
76+
if (from === to) {
77+
return
78+
}
79+
80+
SYMBOL_PREFIXES.forEach(prefix => {
81+
const target_prop = symbol(prefix, to)
82+
if (!hasOwnProperty(array, target_prop)) {
83+
copy_comments(array, array, to, from, prefix, true)
84+
return
85+
}
86+
87+
const comments = array[target_prop]
88+
delete array[target_prop]
89+
90+
copy_comments(array, array, to, from, prefix, true)
91+
define(array, symbol(prefix, from), comments)
92+
})
93+
}
94+
7595
const assign_non_prop_comments = (target, source) => {
7696
NON_PROP_SYMBOL_KEYS.forEach(key => {
7797
const comments = source[key]
@@ -125,6 +145,7 @@ module.exports = {
125145
define,
126146
copy_comments,
127147
copy_all_comments,
148+
swap_comments,
128149
assign_non_prop_comments,
129150

130151
assign (target, source, keys) {

test/array.test.js

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@ const a3 = `[
2929
0
3030
]`
3131

32-
// ret: return value to expect
33-
const texpect = (t, ret, str, r, rr) => {
32+
const texpect = (
33+
t,
34+
// cleaned parsed
35+
ret,
36+
// stringified value from parsed
37+
str,
38+
// parsed value
39+
r,
40+
// real return value
41+
rr
42+
) => {
3443
if (isObject(ret)) {
3544
t.deepEqual(r, ret)
3645
} else {
@@ -110,7 +119,11 @@ const CASES = [
110119
'slice(-1)',
111120
a1,
112121
array => array.slice(- 1),
113-
slice([2], `[
122+
slice(
123+
// cleaned object after parsed and sliced
124+
[2],
125+
// parse, slice and then stringify
126+
`[
114127
// 2
115128
2
116129
]`)
@@ -181,6 +194,24 @@ const CASES = [
181194
1,
182195
// 0
183196
0
197+
]`)
198+
],
199+
[
200+
'reverse, no mess',
201+
`[
202+
0, // 0
203+
// 1
204+
1,
205+
// 2
206+
2
207+
]`,
208+
array => array.reverse(),
209+
unshift([2, 1, 0], `[
210+
// 2
211+
2,
212+
// 1
213+
1,
214+
0 // 0
184215
]`)
185216
],
186217
[
@@ -210,11 +241,16 @@ CASES.forEach(([d, a, run, e, s]) => {
210241

211242
expect(
212243
t,
244+
// Cleaned return value
213245
isArray(ret)
214246
// clean ret
215247
? [...ret]
216248
: ret,
217-
st(parsed), parsed, ret)
249+
// Stringified
250+
st(parsed),
251+
parsed,
252+
ret
253+
)
218254
})
219255
})
220256

0 commit comments

Comments
 (0)