Passed
Push — main ( 10dbfc...61a674 )
by LCS
05:39 queued 03:09
created

node_modules/yallist/yallist.js   F

Complexity

Total Complexity 97
Complexity/F 3.59

Size

Lines of Code 426
Function Count 27

Duplication

Duplicated Lines 92
Ratio 21.6 %

Importance

Changes 0
Metric Value
eloc 272
dl 92
loc 426
rs 2
c 0
b 0
f 0
wmc 97
mnd 70
bc 70
fnc 27
bpm 2.5924
cpm 3.5925
noi 9

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like node_modules/yallist/yallist.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
'use strict'
2
module.exports = Yallist
3
4
Yallist.Node = Node
5
Yallist.create = Yallist
6
7
function Yallist (list) {
8
  var self = this
9
  if (!(self instanceof Yallist)) {
10
    self = new Yallist()
11
  }
12
13
  self.tail = null
14
  self.head = null
15
  self.length = 0
16
17
  if (list && typeof list.forEach === 'function') {
18
    list.forEach(function (item) {
19
      self.push(item)
20
    })
21
  } else if (arguments.length > 0) {
22
    for (var i = 0, l = arguments.length; i < l; i++) {
23
      self.push(arguments[i])
24
    }
25
  }
26
27
  return self
28
}
29
30
Yallist.prototype.removeNode = function (node) {
31
  if (node.list !== this) {
32
    throw new Error('removing node which does not belong to this list')
33
  }
34
35
  var next = node.next
36
  var prev = node.prev
37
38
  if (next) {
39
    next.prev = prev
40
  }
41
42
  if (prev) {
43
    prev.next = next
44
  }
45
46
  if (node === this.head) {
47
    this.head = next
48
  }
49
  if (node === this.tail) {
50
    this.tail = prev
51
  }
52
53
  node.list.length--
54
  node.next = null
55
  node.prev = null
56
  node.list = null
57
58
  return next
59
}
60
61
Yallist.prototype.unshiftNode = function (node) {
62
  if (node === this.head) {
63
    return
64
  }
65
66
  if (node.list) {
67
    node.list.removeNode(node)
68
  }
69
70
  var head = this.head
71
  node.list = this
72
  node.next = head
73
  if (head) {
74
    head.prev = node
75
  }
76
77
  this.head = node
78
  if (!this.tail) {
79
    this.tail = node
80
  }
81
  this.length++
82
}
83
84
Yallist.prototype.pushNode = function (node) {
85
  if (node === this.tail) {
86
    return
87
  }
88
89
  if (node.list) {
90
    node.list.removeNode(node)
91
  }
92
93
  var tail = this.tail
94
  node.list = this
95
  node.prev = tail
96
  if (tail) {
97
    tail.next = node
98
  }
99
100
  this.tail = node
101
  if (!this.head) {
102
    this.head = node
103
  }
104
  this.length++
105
}
106
107
Yallist.prototype.push = function () {
108
  for (var i = 0, l = arguments.length; i < l; i++) {
109
    push(this, arguments[i])
110
  }
111
  return this.length
112
}
113
114
Yallist.prototype.unshift = function () {
115
  for (var i = 0, l = arguments.length; i < l; i++) {
116
    unshift(this, arguments[i])
117
  }
118
  return this.length
119
}
120
121
Yallist.prototype.pop = function () {
122
  if (!this.tail) {
123
    return undefined
124
  }
125
126
  var res = this.tail.value
127
  this.tail = this.tail.prev
128
  if (this.tail) {
129
    this.tail.next = null
130
  } else {
131
    this.head = null
132
  }
133
  this.length--
134
  return res
135
}
136
137
Yallist.prototype.shift = function () {
138
  if (!this.head) {
139
    return undefined
140
  }
141
142
  var res = this.head.value
143
  this.head = this.head.next
144
  if (this.head) {
145
    this.head.prev = null
146
  } else {
147
    this.tail = null
148
  }
149
  this.length--
150
  return res
151
}
152
153
Yallist.prototype.forEach = function (fn, thisp) {
154
  thisp = thisp || this
155
  for (var walker = this.head, i = 0; walker !== null; i++) {
156
    fn.call(thisp, walker.value, i, this)
157
    walker = walker.next
158
  }
159
}
160
161
Yallist.prototype.forEachReverse = function (fn, thisp) {
162
  thisp = thisp || this
163
  for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
164
    fn.call(thisp, walker.value, i, this)
165
    walker = walker.prev
166
  }
167
}
168
169
Yallist.prototype.get = function (n) {
170
  for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
171
    // abort out of the list early if we hit a cycle
172
    walker = walker.next
173
  }
174
  if (i === n && walker !== null) {
175
    return walker.value
176
  }
177
}
178
179
Yallist.prototype.getReverse = function (n) {
180
  for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
181
    // abort out of the list early if we hit a cycle
182
    walker = walker.prev
183
  }
184
  if (i === n && walker !== null) {
185
    return walker.value
186
  }
187
}
188
189
Yallist.prototype.map = function (fn, thisp) {
190
  thisp = thisp || this
191
  var res = new Yallist()
192
  for (var walker = this.head; walker !== null;) {
193
    res.push(fn.call(thisp, walker.value, this))
194
    walker = walker.next
195
  }
196
  return res
197
}
198
199
Yallist.prototype.mapReverse = function (fn, thisp) {
200
  thisp = thisp || this
201
  var res = new Yallist()
202
  for (var walker = this.tail; walker !== null;) {
203
    res.push(fn.call(thisp, walker.value, this))
204
    walker = walker.prev
205
  }
206
  return res
207
}
208
209
Yallist.prototype.reduce = function (fn, initial) {
210
  var acc
211
  var walker = this.head
212
  if (arguments.length > 1) {
213
    acc = initial
214
  } else if (this.head) {
215
    walker = this.head.next
216
    acc = this.head.value
217
  } else {
218
    throw new TypeError('Reduce of empty list with no initial value')
219
  }
220
221
  for (var i = 0; walker !== null; i++) {
222
    acc = fn(acc, walker.value, i)
223
    walker = walker.next
224
  }
225
226
  return acc
227
}
228
229
Yallist.prototype.reduceReverse = function (fn, initial) {
230
  var acc
231
  var walker = this.tail
232
  if (arguments.length > 1) {
233
    acc = initial
234
  } else if (this.tail) {
235
    walker = this.tail.prev
236
    acc = this.tail.value
237
  } else {
238
    throw new TypeError('Reduce of empty list with no initial value')
239
  }
240
241
  for (var i = this.length - 1; walker !== null; i--) {
242
    acc = fn(acc, walker.value, i)
243
    walker = walker.prev
244
  }
245
246
  return acc
247
}
248
249
Yallist.prototype.toArray = function () {
250
  var arr = new Array(this.length)
251
  for (var i = 0, walker = this.head; walker !== null; i++) {
252
    arr[i] = walker.value
253
    walker = walker.next
254
  }
255
  return arr
256
}
257
258
Yallist.prototype.toArrayReverse = function () {
259
  var arr = new Array(this.length)
260
  for (var i = 0, walker = this.tail; walker !== null; i++) {
261
    arr[i] = walker.value
262
    walker = walker.prev
263
  }
264
  return arr
265
}
266
267
Yallist.prototype.slice = function (from, to) {
268
  to = to || this.length
269
  if (to < 0) {
270
    to += this.length
271
  }
272
  from = from || 0
273
  if (from < 0) {
274
    from += this.length
275
  }
276
  var ret = new Yallist()
277
  if (to < from || to < 0) {
278
    return ret
279
  }
280
  if (from < 0) {
281
    from = 0
282
  }
283
  if (to > this.length) {
284
    to = this.length
285
  }
286
  for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
287
    walker = walker.next
288
  }
289
  for (; walker !== null && i < to; i++, walker = walker.next) {
290
    ret.push(walker.value)
291
  }
292
  return ret
293
}
294
295
Yallist.prototype.sliceReverse = function (from, to) {
296
  to = to || this.length
297
  if (to < 0) {
298
    to += this.length
299
  }
300
  from = from || 0
301
  if (from < 0) {
302
    from += this.length
303
  }
304
  var ret = new Yallist()
305
  if (to < from || to < 0) {
306
    return ret
307
  }
308
  if (from < 0) {
309
    from = 0
310
  }
311
  if (to > this.length) {
312
    to = this.length
313
  }
314
  for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
315
    walker = walker.prev
316
  }
317
  for (; walker !== null && i > from; i--, walker = walker.prev) {
318
    ret.push(walker.value)
319
  }
320
  return ret
321
}
322
323
Yallist.prototype.splice = function (start, deleteCount /*, ...nodes */) {
324
  if (start > this.length) {
325
    start = this.length - 1
326
  }
327
  if (start < 0) {
328
    start = this.length + start;
329
  }
330
331
  for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
332
    walker = walker.next
333
  }
334
335
  var ret = []
336
  for (var i = 0; walker && i < deleteCount; i++) {
337
    ret.push(walker.value)
338
    walker = this.removeNode(walker)
339
  }
340
  if (walker === null) {
341
    walker = this.tail
342
  }
343
344
  if (walker !== this.head && walker !== this.tail) {
345
    walker = walker.prev
346
  }
347
348
  for (var i = 2; i < arguments.length; i++) {
349
    walker = insert(this, walker, arguments[i])
350
  }
351
  return ret;
352
}
353
354
Yallist.prototype.reverse = function () {
355
  var head = this.head
356
  var tail = this.tail
357
  for (var walker = head; walker !== null; walker = walker.prev) {
358
    var p = walker.prev
359
    walker.prev = walker.next
360
    walker.next = p
361
  }
362
  this.head = tail
363
  this.tail = head
364
  return this
365
}
366
367
function insert (self, node, value) {
368
  var inserted = node === self.head ?
369
    new Node(value, null, node, self) :
370
    new Node(value, node, node.next, self)
371
372
  if (inserted.next === null) {
373
    self.tail = inserted
374
  }
375
  if (inserted.prev === null) {
376
    self.head = inserted
377
  }
378
379
  self.length++
380
381
  return inserted
382
}
383
384
function push (self, item) {
385
  self.tail = new Node(item, self.tail, null, self)
386
  if (!self.head) {
387
    self.head = self.tail
388
  }
389
  self.length++
390
}
391
392
function unshift (self, item) {
393
  self.head = new Node(item, null, self.head, self)
394
  if (!self.tail) {
395
    self.tail = self.head
396
  }
397
  self.length++
398
}
399
400
function Node (value, prev, next, list) {
401
  if (!(this instanceof Node)) {
402
    return new Node(value, prev, next, list)
403
  }
404
405
  this.list = list
406
  this.value = value
407
408
  if (prev) {
409
    prev.next = this
410
    this.prev = prev
411
  } else {
412
    this.prev = null
413
  }
414
415
  if (next) {
416
    next.prev = this
417
    this.next = next
418
  } else {
419
    this.next = null
420
  }
421
}
422
423
try {
424
  // add if support for Symbol.iterator is present
425
  require('./iterator.js')(Yallist)
426
} catch (er) {}
427