From 9e4611c6c19b28e28ea84e6c20f38ac9f03483c3 Mon Sep 17 00:00:00 2001 From: Zijian Liu Date: Fri, 4 Dec 2020 12:10:22 +0800 Subject: [PATCH] fs: refactor to use private fields --- lib/internal/fs/dir.js | 135 +++++++++++++++++++-------------------- lib/internal/fs/utils.js | 18 +++--- 2 files changed, 73 insertions(+), 80 deletions(-) diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 6eeeb84bda9d70..c49f03f70139cf 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -7,7 +7,6 @@ const { FunctionPrototypeBind, ObjectDefineProperty, PromiseReject, - Symbol, SymbolAsyncIterator, } = primordials; @@ -35,84 +34,78 @@ const { validateUint32 } = require('internal/validators'); -const kDirHandle = Symbol('kDirHandle'); -const kDirPath = Symbol('kDirPath'); -const kDirBufferedEntries = Symbol('kDirBufferedEntries'); -const kDirClosed = Symbol('kDirClosed'); -const kDirOptions = Symbol('kDirOptions'); -const kDirReadImpl = Symbol('kDirReadImpl'); -const kDirReadPromisified = Symbol('kDirReadPromisified'); -const kDirClosePromisified = Symbol('kDirClosePromisified'); -const kDirOperationQueue = Symbol('kDirOperationQueue'); - class Dir { + #handle = undefined; + #path = undefined; + #options = undefined; + #bufferedEntries = []; + #dirClosed = false; + // Either `null` or an Array of pending operations (= functions to be called + // once the current operation is done). + #operationQueue = null; + #readPromisified = undefined; + #closePromisified = undefined; + constructor(handle, path, options) { if (handle == null) throw new ERR_MISSING_ARGS('handle'); - this[kDirHandle] = handle; - this[kDirBufferedEntries] = []; - this[kDirPath] = path; - this[kDirClosed] = false; - - // Either `null` or an Array of pending operations (= functions to be called - // once the current operation is done). - this[kDirOperationQueue] = null; - - this[kDirOptions] = { + this.#handle = handle; + this.#path = path; + this.#options = { bufferSize: 32, ...getOptions(options, { encoding: 'utf8' }) }; - validateUint32(this[kDirOptions].bufferSize, 'options.bufferSize', true); - - this[kDirReadPromisified] = FunctionPrototypeBind( - internalUtil.promisify(this[kDirReadImpl]), this, false); - this[kDirClosePromisified] = FunctionPrototypeBind( + this.#readPromisified = FunctionPrototypeBind( + internalUtil.promisify(this.#readImpl), this, false); + this.#closePromisified = this.#closePromisified = FunctionPrototypeBind( internalUtil.promisify(this.close), this); + + validateUint32(this.#options.bufferSize, 'options.bufferSize', true); } get path() { - return this[kDirPath]; + return this.#path; } read(callback) { - return this[kDirReadImpl](true, callback); + return this.#readImpl(true, callback); } - [kDirReadImpl](maybeSync, callback) { - if (this[kDirClosed] === true) { + #readImpl(maybeSync, callback) { + if (this.#dirClosed === true) { throw new ERR_DIR_CLOSED(); } if (callback === undefined) { - return this[kDirReadPromisified](); + return this.#readPromisified(); } else if (typeof callback !== 'function') { throw new ERR_INVALID_CALLBACK(callback); } - if (this[kDirOperationQueue] !== null) { - ArrayPrototypePush(this[kDirOperationQueue], () => { - this[kDirReadImpl](maybeSync, callback); + if (this.#operationQueue !== null) { + ArrayPrototypePush(this.#operationQueue, () => { + this.#readImpl(maybeSync, callback); }); return; } - if (this[kDirBufferedEntries].length > 0) { + if (this.#bufferedEntries.length > 0) { const [ name, type ] = - ArrayPrototypeSplice(this[kDirBufferedEntries], 0, 2); + ArrayPrototypeSplice(this.#bufferedEntries, 0, 2); if (maybeSync) - process.nextTick(getDirent, this[kDirPath], name, type, callback); + process.nextTick(getDirent, this.#path, name, type, callback); else - getDirent(this[kDirPath], name, type, callback); + getDirent(this.#path, name, type, callback); return; } const req = new FSReqCallback(); req.oncomplete = (err, result) => { process.nextTick(() => { - const queue = this[kDirOperationQueue]; - this[kDirOperationQueue] = null; + const queue = this.#operationQueue; + this.#operationQueue = null; for (const op of queue) op(); }); @@ -120,37 +113,37 @@ class Dir { return callback(err, result); } - this[kDirBufferedEntries] = ArrayPrototypeSlice(result, 2); - getDirent(this[kDirPath], result[0], result[1], callback); + this.#bufferedEntries = ArrayPrototypeSlice(result, 2); + getDirent(this.#path, result[0], result[1], callback); }; - this[kDirOperationQueue] = []; - this[kDirHandle].read( - this[kDirOptions].encoding, - this[kDirOptions].bufferSize, + this.#operationQueue = []; + this.#handle.read( + this.#options.encoding, + this.#options.bufferSize, req ); } readSync() { - if (this[kDirClosed] === true) { + if (this.#dirClosed === true) { throw new ERR_DIR_CLOSED(); } - if (this[kDirOperationQueue] !== null) { + if (this.#operationQueue !== null) { throw new ERR_DIR_CONCURRENT_OPERATION(); } - if (this[kDirBufferedEntries].length > 0) { + if (this.#bufferedEntries.length > 0) { const [ name, type ] = - ArrayPrototypeSplice(this[kDirBufferedEntries], 0, 2); - return getDirent(this[kDirPath], name, type); + ArrayPrototypeSplice(this.#bufferedEntries, 0, 2); + return getDirent(this.#path, name, type); } - const ctx = { path: this[kDirPath] }; - const result = this[kDirHandle].read( - this[kDirOptions].encoding, - this[kDirOptions].bufferSize, + const ctx = { path: this.#path }; + const result = this.#handle.read( + this.#options.encoding, + this.#options.bufferSize, undefined, ctx ); @@ -160,17 +153,17 @@ class Dir { return result; } - this[kDirBufferedEntries] = ArrayPrototypeSlice(result, 2); - return getDirent(this[kDirPath], result[0], result[1]); + this.#bufferedEntries = ArrayPrototypeSlice(result, 2); + return getDirent(this.#path, result[0], result[1]); } close(callback) { // Promise if (callback === undefined) { - if (this[kDirClosed] === true) { + if (this.#dirClosed === true) { return PromiseReject(new ERR_DIR_CLOSED()); } - return this[kDirClosePromisified](); + return this.#closePromisified(); } // callback @@ -178,36 +171,36 @@ class Dir { throw new ERR_INVALID_CALLBACK(callback); } - if (this[kDirClosed] === true) { + if (this.#dirClosed === true) { process.nextTick(callback, new ERR_DIR_CLOSED()); return; } - if (this[kDirOperationQueue] !== null) { - this[kDirOperationQueue].push(() => { + if (this.#operationQueue !== null) { + this.#operationQueue.push(() => { this.close(callback); }); return; } - this[kDirClosed] = true; + this.#dirClosed = true; const req = new FSReqCallback(); req.oncomplete = callback; - this[kDirHandle].close(req); + this.#handle.close(req); } closeSync() { - if (this[kDirClosed] === true) { + if (this.#dirClosed === true) { throw new ERR_DIR_CLOSED(); } - if (this[kDirOperationQueue] !== null) { + if (this.#operationQueue !== null) { throw new ERR_DIR_CONCURRENT_OPERATION(); } - this[kDirClosed] = true; - const ctx = { path: this[kDirPath] }; - const result = this[kDirHandle].close(undefined, ctx); + this.#dirClosed = true; + const ctx = { path: this.#path }; + const result = this.#handle.close(undefined, ctx); handleErrorFromBinding(ctx); return result; } @@ -215,14 +208,14 @@ class Dir { async* entries() { try { while (true) { - const result = await this[kDirReadPromisified](); + const result = await this.#readPromisified(); if (result === null) { break; } yield result; } } finally { - await this[kDirClosePromisified](); + await this.#closePromisified(); } } } diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index d5f3b4c78f16a2..5b4e69ffd46701 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -50,7 +50,6 @@ const { validateUint32 } = require('internal/validators'); const pathModule = require('path'); -const kType = Symbol('type'); const kStats = Symbol('stats'); const assert = require('internal/assert'); @@ -135,37 +134,38 @@ function assertEncoding(encoding) { } class Dirent { + #type = undefined; constructor(name, type) { this.name = name; - this[kType] = type; + this.#type = type; } isDirectory() { - return this[kType] === UV_DIRENT_DIR; + return this.#type === UV_DIRENT_DIR; } isFile() { - return this[kType] === UV_DIRENT_FILE; + return this.#type === UV_DIRENT_FILE; } isBlockDevice() { - return this[kType] === UV_DIRENT_BLOCK; + return this.#type === UV_DIRENT_BLOCK; } isCharacterDevice() { - return this[kType] === UV_DIRENT_CHAR; + return this.#type === UV_DIRENT_CHAR; } isSymbolicLink() { - return this[kType] === UV_DIRENT_LINK; + return this.#type === UV_DIRENT_LINK; } isFIFO() { - return this[kType] === UV_DIRENT_FIFO; + return this.#type === UV_DIRENT_FIFO; } isSocket() { - return this[kType] === UV_DIRENT_SOCKET; + return this.#type === UV_DIRENT_SOCKET; } }