Skip to content

Commit a2a7478

Browse files
committed
fs: convert stats to class and load dates lazily
1 parent 7981e2e commit a2a7478

File tree

1 file changed

+147
-74
lines changed

1 file changed

+147
-74
lines changed

lib/internal/fs/utils.js

Lines changed: 147 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ const {
77
DateNow,
88
DatePrototypeGetTime,
99
ErrorCaptureStackTrace,
10-
FunctionPrototypeCall,
1110
Number,
1211
NumberIsFinite,
1312
MathMin,
1413
MathRound,
14+
ObjectDefineProperties,
1515
ObjectIs,
16-
ObjectSetPrototypeOf,
17-
ReflectApply,
1816
ReflectOwnKeys,
1917
RegExpPrototypeSymbolReplace,
2018
StringPrototypeEndsWith,
@@ -382,47 +380,49 @@ function preprocessSymlinkDestination(path, type, linkPath) {
382380
}
383381

384382
// Constructor for file stats.
385-
function StatsBase(dev, mode, nlink, uid, gid, rdev, blksize,
386-
ino, size, blocks) {
387-
this.dev = dev;
388-
this.mode = mode;
389-
this.nlink = nlink;
390-
this.uid = uid;
391-
this.gid = gid;
392-
this.rdev = rdev;
393-
this.blksize = blksize;
394-
this.ino = ino;
395-
this.size = size;
396-
this.blocks = blocks;
397-
}
383+
class StatsBase {
384+
constructor(dev, mode, nlink, uid, gid, rdev, blksize,
385+
ino, size, blocks) {
386+
this.dev = dev;
387+
this.mode = mode;
388+
this.nlink = nlink;
389+
this.uid = uid;
390+
this.gid = gid;
391+
this.rdev = rdev;
392+
this.blksize = blksize;
393+
this.ino = ino;
394+
this.size = size;
395+
this.blocks = blocks;
396+
}
398397

399-
StatsBase.prototype.isDirectory = function() {
400-
return this._checkModeProperty(S_IFDIR);
401-
};
398+
isDirectory() {
399+
return this._checkModeProperty(S_IFDIR);
400+
}
402401

403-
StatsBase.prototype.isFile = function() {
404-
return this._checkModeProperty(S_IFREG);
405-
};
402+
isFile() {
403+
return this._checkModeProperty(S_IFREG);
404+
}
406405

407-
StatsBase.prototype.isBlockDevice = function() {
408-
return this._checkModeProperty(S_IFBLK);
409-
};
406+
isBlockDevice() {
407+
return this._checkModeProperty(S_IFBLK);
408+
}
410409

411-
StatsBase.prototype.isCharacterDevice = function() {
412-
return this._checkModeProperty(S_IFCHR);
413-
};
410+
isCharacterDevice() {
411+
return this._checkModeProperty(S_IFCHR);
412+
}
414413

415-
StatsBase.prototype.isSymbolicLink = function() {
416-
return this._checkModeProperty(S_IFLNK);
417-
};
414+
isSymbolicLink() {
415+
return this._checkModeProperty(S_IFLNK);
416+
}
418417

419-
StatsBase.prototype.isFIFO = function() {
420-
return this._checkModeProperty(S_IFIFO);
421-
};
418+
isFIFO() {
419+
return this._checkModeProperty(S_IFIFO);
420+
}
422421

423-
StatsBase.prototype.isSocket = function() {
424-
return this._checkModeProperty(S_IFSOCK);
425-
};
422+
isSocket() {
423+
return this._checkModeProperty(S_IFSOCK);
424+
}
425+
}
426426

427427
const kNsPerMsBigInt = 10n ** 6n;
428428
const kNsPerSecBigInt = 10n ** 9n;
@@ -448,29 +448,65 @@ function dateFromMs(ms) {
448448
return new Date(MathRound(Number(ms)));
449449
}
450450

451-
function BigIntStats(dev, mode, nlink, uid, gid, rdev, blksize,
452-
ino, size, blocks,
453-
atimeNs, mtimeNs, ctimeNs, birthtimeNs) {
454-
ReflectApply(StatsBase, this, [dev, mode, nlink, uid, gid, rdev, blksize,
455-
ino, size, blocks]);
456-
457-
this.atimeMs = atimeNs / kNsPerMsBigInt;
458-
this.mtimeMs = mtimeNs / kNsPerMsBigInt;
459-
this.ctimeMs = ctimeNs / kNsPerMsBigInt;
460-
this.birthtimeMs = birthtimeNs / kNsPerMsBigInt;
461-
this.atimeNs = atimeNs;
462-
this.mtimeNs = mtimeNs;
463-
this.ctimeNs = ctimeNs;
464-
this.birthtimeNs = birthtimeNs;
465-
this.atime = dateFromMs(this.atimeMs);
466-
this.mtime = dateFromMs(this.mtimeMs);
467-
this.ctime = dateFromMs(this.ctimeMs);
468-
this.birthtime = dateFromMs(this.birthtimeMs);
451+
class BigIntStats extends StatsBase {
452+
#atime;
453+
#mtime;
454+
#ctime;
455+
#birthtime;
456+
457+
constructor(dev, mode, nlink, uid, gid, rdev, blksize,
458+
ino, size, blocks,
459+
atimeNs, mtimeNs, ctimeNs, birthtimeNs) {
460+
super(dev, mode, nlink, uid, gid, rdev, blksize,
461+
ino, size, blocks);
462+
463+
this.atimeMs = atimeNs / kNsPerMsBigInt;
464+
this.mtimeMs = mtimeNs / kNsPerMsBigInt;
465+
this.ctimeMs = ctimeNs / kNsPerMsBigInt;
466+
this.birthtimeMs = birthtimeNs / kNsPerMsBigInt;
467+
this.atimeNs = atimeNs;
468+
this.mtimeNs = mtimeNs;
469+
this.ctimeNs = ctimeNs;
470+
this.birthtimeNs = birthtimeNs;
471+
472+
ObjectDefineProperties(this, {
473+
__proto__: null,
474+
atime: {
475+
__proto__: null,
476+
enumerable: true,
477+
get() {
478+
this.#atime ??= dateFromMs(this.atimeMs);
479+
return this.#atime;
480+
},
481+
},
482+
mtime: {
483+
__proto__: null,
484+
enumerable: true,
485+
get() {
486+
this.#mtime ??= dateFromMs(this.mtimeMs);
487+
return this.#mtime;
488+
},
489+
},
490+
ctime: {
491+
__proto__: null,
492+
enumerable: true,
493+
get() {
494+
this.#ctime ??= dateFromMs(this.ctimeMs);
495+
return this.#ctime;
496+
},
497+
},
498+
birthtime: {
499+
__proto__: null,
500+
enumerable: true,
501+
get() {
502+
this.#birthtime ??= dateFromMs(this.birthtimeMs);
503+
return this.#birthtime;
504+
},
505+
},
506+
});
507+
}
469508
}
470509

471-
ObjectSetPrototypeOf(BigIntStats.prototype, StatsBase.prototype);
472-
ObjectSetPrototypeOf(BigIntStats, StatsBase);
473-
474510
BigIntStats.prototype._checkModeProperty = function(property) {
475511
if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
476512
property === S_IFSOCK)) {
@@ -479,24 +515,61 @@ BigIntStats.prototype._checkModeProperty = function(property) {
479515
return (this.mode & BigInt(S_IFMT)) === BigInt(property);
480516
};
481517

482-
function Stats(dev, mode, nlink, uid, gid, rdev, blksize,
483-
ino, size, blocks,
484-
atimeMs, mtimeMs, ctimeMs, birthtimeMs) {
485-
FunctionPrototypeCall(StatsBase, this, dev, mode, nlink, uid, gid, rdev,
486-
blksize, ino, size, blocks);
487-
this.atimeMs = atimeMs;
488-
this.mtimeMs = mtimeMs;
489-
this.ctimeMs = ctimeMs;
490-
this.birthtimeMs = birthtimeMs;
491-
this.atime = dateFromMs(atimeMs);
492-
this.mtime = dateFromMs(mtimeMs);
493-
this.ctime = dateFromMs(ctimeMs);
494-
this.birthtime = dateFromMs(birthtimeMs);
518+
class Stats extends StatsBase {
519+
#atime;
520+
#mtime;
521+
#ctime;
522+
#birthtime;
523+
524+
constructor(dev, mode, nlink, uid, gid, rdev, blksize,
525+
ino, size, blocks,
526+
atimeMs, mtimeMs, ctimeMs, birthtimeMs) {
527+
super(dev, mode, nlink, uid, gid, rdev,
528+
blksize, ino, size, blocks);
529+
530+
this.atimeMs = atimeMs;
531+
this.mtimeMs = mtimeMs;
532+
this.ctimeMs = ctimeMs;
533+
this.birthtimeMs = birthtimeMs;
534+
535+
ObjectDefineProperties(this, {
536+
__proto__: null,
537+
atime: {
538+
__proto__: null,
539+
enumerable: true,
540+
get() {
541+
this.#atime ??= dateFromMs(this.atimeMs);
542+
return this.#atime;
543+
},
544+
},
545+
mtime: {
546+
__proto__: null,
547+
enumerable: true,
548+
get() {
549+
this.#mtime ??= dateFromMs(this.mtimeMs);
550+
return this.#mtime;
551+
},
552+
},
553+
ctime: {
554+
__proto__: null,
555+
enumerable: true,
556+
get() {
557+
this.#ctime ??= dateFromMs(this.ctimeMs);
558+
return this.#ctime;
559+
},
560+
},
561+
birthtime: {
562+
__proto__: null,
563+
enumerable: true,
564+
get() {
565+
this.#birthtime ??= dateFromMs(this.birthtimeMs);
566+
return this.#birthtime;
567+
},
568+
},
569+
});
570+
}
495571
}
496572

497-
ObjectSetPrototypeOf(Stats.prototype, StatsBase.prototype);
498-
ObjectSetPrototypeOf(Stats, StatsBase);
499-
500573
// HACK: Workaround for https://github.com/standard-things/esm/issues/821.
501574
// TODO(ronag): Remove this as soon as `esm` publishes a fixed version.
502575
Stats.prototype.isFile = StatsBase.prototype.isFile;

0 commit comments

Comments
 (0)