From 9e5d691ee4d8ba775e6a25cfa4289b1cf568a48b Mon Sep 17 00:00:00 2001 From: ZYSzys Date: Fri, 4 Oct 2019 00:35:41 +0800 Subject: [PATCH] lib: introduce no-mixed-operators eslint rule to lib PR-URL: https://github.com/nodejs/node/pull/29834 Reviewed-By: Anna Henningsen Reviewed-By: Gus Caplan Reviewed-By: Luigi Pinca Reviewed-By: Ruben Bridgewater Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Trivikram Kamat --- lib/.eslintrc.yaml | 3 +++ lib/_http_client.js | 2 +- lib/_stream_readable.js | 2 +- lib/_tls_wrap.js | 4 ++-- lib/assert.js | 4 ++-- lib/internal/assert/assertion_error.js | 2 +- lib/internal/child_process.js | 2 +- lib/internal/cluster/child.js | 2 +- lib/internal/errors.js | 4 ++-- lib/internal/fs/utils.js | 6 +++--- lib/internal/modules/cjs/loader.js | 2 +- lib/internal/readline/utils.js | 26 +++++++++++++------------- lib/internal/tty.js | 2 +- lib/internal/url.js | 2 +- lib/internal/util/comparisons.js | 6 +++--- lib/internal/util/inspect.js | 24 ++++++++++++------------ lib/path.js | 12 ++++++------ lib/readline.js | 2 +- lib/url.js | 10 +++++----- lib/util.js | 2 +- 20 files changed, 61 insertions(+), 58 deletions(-) diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index 824bd32980da8c..b7e8e1f4fbeb4a 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -4,6 +4,9 @@ env: rules: prefer-object-spread: error no-buffer-constructor: error + no-mixed-operators: + - error + - groups: [[ "&&", "||" ]] no-restricted-globals: - error - name: JSON diff --git a/lib/_http_client.js b/lib/_http_client.js index 91dd398ce6639c..0eae2e7e58dd04 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -144,7 +144,7 @@ function ClientRequest(input, options, cb) { } const defaultPort = options.defaultPort || - this.agent && this.agent.defaultPort; + (this.agent && this.agent.defaultPort); const port = options.port = options.port || defaultPort || 80; const host = options.host = validateHost(options.hostname, 'hostname') || diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 6c2bbb3495a3a3..d3198c7545f1d8 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -260,7 +260,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { er = chunkInvalid(state, chunk); if (er) { errorOrDestroy(stream, er); - } else if (state.objectMode || chunk && chunk.length > 0) { + } else if (state.objectMode || (chunk && chunk.length > 0)) { if (typeof chunk !== 'string' && !state.objectMode && // Do not use Object.getPrototypeOf as it is slower since V8 7.3. diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index db6f6b5e765f0b..9c3fe656a7ce80 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -149,8 +149,8 @@ function loadSession(hello) { if (hello.sessionId.length <= 0 || hello.tlsTicket || - owner.server && - !owner.server.emit('resumeSession', hello.sessionId, onSession)) { + (owner.server && + !owner.server.emit('resumeSession', hello.sessionId, onSession))) { // Sessions without identifiers can't be resumed. // Sessions with tickets can be resumed directly from the ticket, no server // session storage is necessary. diff --git a/lib/assert.js b/lib/assert.js index 562c9628c9dacb..cb9cef6b902a1e 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -647,9 +647,9 @@ function checkIsPromise(obj) { // way. Do not accept thenables that use a function as `obj` and that have no // `catch` handler. return isPromise(obj) || - obj !== null && typeof obj === 'object' && + (obj !== null && typeof obj === 'object' && typeof obj.then === 'function' && - typeof obj.catch === 'function'; + typeof obj.catch === 'function'); } async function waitForActual(promiseFn) { diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index 3734796e2d2a2d..0b57bf2cb200c5 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -349,7 +349,7 @@ class AssertionError extends Error { // In case "actual" is an object or a function, it should not be // reference equal. if (operator === 'notStrictEqual' && - (typeof actual === 'object' && actual !== null || + ((typeof actual === 'object' && actual !== null) || typeof actual === 'function')) { base = kReadableOperator.notStrictEqualObject; } diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index a0f083d8deb58e..5612d31bb5738d 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -934,7 +934,7 @@ function getValidStdio(stdio, sync) { if (stdio === 'ignore') { acc.push({ type: 'ignore' }); - } else if (stdio === 'pipe' || typeof stdio === 'number' && stdio < 0) { + } else if (stdio === 'pipe' || (typeof stdio === 'number' && stdio < 0)) { var a = { type: 'pipe', readable: i === 0, diff --git a/lib/internal/cluster/child.js b/lib/internal/cluster/child.js index e7bddc1d0bc1f9..097c6dafae0172 100644 --- a/lib/internal/cluster/child.js +++ b/lib/internal/cluster/child.js @@ -100,7 +100,7 @@ cluster._getServer = function(obj, options, cb) { cluster.worker.state = 'listening'; const address = obj.address(); message.act = 'listening'; - message.port = address && address.port || options.port; + message.port = (address && address.port) || options.port; send(message); }); }; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index daf6831be05f71..c7e4c4783e7d2e 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -656,8 +656,8 @@ const fatalExceptionStackEnhancers = { colors: defaultColors } } = lazyInternalUtilInspect(); - const colors = internalBinding('util').guessHandleType(2) === 'TTY' && - require('internal/tty').hasColors() || + const colors = (internalBinding('util').guessHandleType(2) === 'TTY' && + require('internal/tty').hasColors()) || defaultColors; try { return inspect(error, { colors }); diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 80f0784681b588..efb54ca393cc8a 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -204,9 +204,9 @@ const nullCheck = hideStackFrames((path, propName, throwError = true) => { const pathIsUint8Array = isUint8Array(path); // We can only perform meaningful checks on strings and Uint8Arrays. - if (!pathIsString && !pathIsUint8Array || - pathIsString && !path.includes('\u0000') || - pathIsUint8Array && !path.includes(0)) { + if ((!pathIsString && !pathIsUint8Array) || + (pathIsString && !path.includes('\u0000')) || + (pathIsUint8Array && !path.includes(0))) { return; } diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index eab006935b0cad..9933839a055a47 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -733,7 +733,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { if (Array.isArray(options.paths)) { const isRelative = request.startsWith('./') || request.startsWith('../') || - (isWindows && request.startsWith('.\\') || + ((isWindows && request.startsWith('.\\')) || request.startsWith('..\\')); if (isRelative) { diff --git a/lib/internal/readline/utils.js b/lib/internal/readline/utils.js index f72a03bb3915f4..31de512f74ba85 100644 --- a/lib/internal/readline/utils.js +++ b/lib/internal/readline/utils.js @@ -108,30 +108,30 @@ if (internalBinding('config').hasIntl) { code === 0x2329 || // LEFT-POINTING ANGLE BRACKET code === 0x232a || // RIGHT-POINTING ANGLE BRACKET // CJK Radicals Supplement .. Enclosed CJK Letters and Months - code >= 0x2e80 && code <= 0x3247 && code !== 0x303f || + (code >= 0x2e80 && code <= 0x3247 && code !== 0x303f) || // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A - code >= 0x3250 && code <= 0x4dbf || + (code >= 0x3250 && code <= 0x4dbf) || // CJK Unified Ideographs .. Yi Radicals - code >= 0x4e00 && code <= 0xa4c6 || + (code >= 0x4e00 && code <= 0xa4c6) || // Hangul Jamo Extended-A - code >= 0xa960 && code <= 0xa97c || + (code >= 0xa960 && code <= 0xa97c) || // Hangul Syllables - code >= 0xac00 && code <= 0xd7a3 || + (code >= 0xac00 && code <= 0xd7a3) || // CJK Compatibility Ideographs - code >= 0xf900 && code <= 0xfaff || + (code >= 0xf900 && code <= 0xfaff) || // Vertical Forms - code >= 0xfe10 && code <= 0xfe19 || + (code >= 0xfe10 && code <= 0xfe19) || // CJK Compatibility Forms .. Small Form Variants - code >= 0xfe30 && code <= 0xfe6b || + (code >= 0xfe30 && code <= 0xfe6b) || // Halfwidth and Fullwidth Forms - code >= 0xff01 && code <= 0xff60 || - code >= 0xffe0 && code <= 0xffe6 || + (code >= 0xff01 && code <= 0xff60) || + (code >= 0xffe0 && code <= 0xffe6) || // Kana Supplement - code >= 0x1b000 && code <= 0x1b001 || + (code >= 0x1b000 && code <= 0x1b001) || // Enclosed Ideographic Supplement - code >= 0x1f200 && code <= 0x1f251 || + (code >= 0x1f200 && code <= 0x1f251) || // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - code >= 0x20000 && code <= 0x3fffd + (code >= 0x20000 && code <= 0x3fffd) ); }; } diff --git a/lib/internal/tty.js b/lib/internal/tty.js index 6fd14145fcc12a..faf5df9b42e6b2 100644 --- a/lib/internal/tty.js +++ b/lib/internal/tty.js @@ -200,7 +200,7 @@ function getColorDepth(env = process.env) { function hasColors(count, env) { if (env === undefined && - (count === undefined || typeof count === 'object' && count !== null)) { + (count === undefined || (typeof count === 'object' && count !== null))) { env = count; count = 16; } else { diff --git a/lib/internal/url.js b/lib/internal/url.js index a920511df489dc..fde643bea370c8 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1363,7 +1363,7 @@ function pathToFileURL(filepath) { // path.resolve strips trailing slashes so we must add them back const filePathLast = filepath.charCodeAt(filepath.length - 1); if ((filePathLast === CHAR_FORWARD_SLASH || - isWindows && filePathLast === CHAR_BACKWARD_SLASH) && + (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && resolved[resolved.length - 1] !== path.sep) resolved += '/'; const outURL = new URL('file://'); diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index a895da2ad12945..b3256716c38b63 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -294,7 +294,7 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) { if (aKeys.length === 0 && (iterationType === kNoIterator || - iterationType === kIsArray && val1.length === 0 || + (iterationType === kIsArray && val1.length === 0) || val1.size === 0)) { return true; } @@ -383,7 +383,7 @@ function mapMightHaveLoosePrim(a, b, prim, item, memo) { return altValue; } const curB = b.get(altValue); - if (curB === undefined && !b.has(altValue) || + if ((curB === undefined && !b.has(altValue)) || !innerDeepEqual(item, curB, false, memo)) { return false; } @@ -470,7 +470,7 @@ function mapEquiv(a, b, strict, memo) { // By directly retrieving the value we prevent another b.has(key) check in // almost all possible cases. const item2 = b.get(key); - if ((item2 === undefined && !b.has(key) || + if (((item2 === undefined && !b.has(key)) || !innerDeepEqual(item1, item2, strict, memo))) { if (strict) return false; diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index f63fafd01f89e0..efe8f23e08aeae 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -599,10 +599,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { // Only list the tag in case it's non-enumerable / not an own property. // Otherwise we'd print this twice. if (typeof tag !== 'string' || - tag !== '' && + (tag !== '' && (ctx.showHidden ? hasOwnProperty : propertyIsEnumerable)( value, Symbol.toStringTag - )) { + ))) { tag = ''; } let base = ''; @@ -686,7 +686,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { const prefix = getPrefix(constructor, tag, 'RegExp'); if (prefix !== 'RegExp ') base = `${prefix}${base}`; - if (keys.length === 0 || recurseTimes > ctx.depth && ctx.depth !== null) + if (keys.length === 0 || (recurseTimes > ctx.depth && ctx.depth !== null)) return ctx.stylize(base, 'regexp'); } else if (isDate(value)) { // Make dates with properties first say the date @@ -911,14 +911,14 @@ function formatError(err, constructor, tag, ctx) { const name = err.name || 'Error'; let len = name.length; if (constructor === null || - name.endsWith('Error') && + (name.endsWith('Error') && stack.startsWith(name) && - (stack.length === len || stack[len] === ':' || stack[len] === '\n')) { + (stack.length === len || stack[len] === ':' || stack[len] === '\n'))) { let fallback = 'Error'; if (constructor === null) { const start = stack.match(/^([A-Z][a-z_ A-Z0-9[\]()-]+)(?::|\n {4}at)/) || stack.match(/^([a-z_A-Z0-9-]*Error)$/); - fallback = start && start[1] || ''; + fallback = (start && start[1]) || ''; len = fallback.length; fallback = fallback || 'Error'; } @@ -936,7 +936,7 @@ function formatError(err, constructor, tag, ctx) { } } // Ignore the error message if it's contained in the stack. - let pos = err.message && stack.indexOf(err.message) || -1; + let pos = (err.message && stack.indexOf(err.message)) || -1; if (pos !== -1) pos += err.message.length; // Wrap the error in brackets in case it has no stack trace. @@ -1416,8 +1416,8 @@ function formatProperty(ctx, value, recurseTimes, key, type) { const s = ctx.stylize; const sp = 'special'; if (ctx.getters && (ctx.getters === true || - ctx.getters === 'get' && desc.set === undefined || - ctx.getters === 'set' && desc.set !== undefined)) { + (ctx.getters === 'get' && desc.set === undefined) || + (ctx.getters === 'set' && desc.set !== undefined))) { try { const tmp = value[key]; ctx.indentationLvl += 2; @@ -1594,15 +1594,15 @@ function formatWithOptions(inspectOptions, ...args) { let constr; if (typeof tempArg !== 'object' || tempArg === null || - typeof tempArg.toString === 'function' && + (typeof tempArg.toString === 'function' && // A direct own property. (hasOwnProperty(tempArg, 'toString') || // A direct own property on the constructor prototype in // case the constructor is not an built-in object. - (constr = tempArg.constructor) && + ((constr = tempArg.constructor) && !builtInObjects.has(constr.name) && constr.prototype && - hasOwnProperty(constr.prototype, 'toString'))) { + hasOwnProperty(constr.prototype, 'toString'))))) { tempStr = String(tempArg); } else { tempStr = inspect(tempArg, { diff --git a/lib/path.js b/lib/path.js index 884da4cd8e6822..395fe1f35702c4 100644 --- a/lib/path.js +++ b/lib/path.js @@ -44,8 +44,8 @@ function isPosixPathSeparator(code) { } function isWindowsDeviceRoot(code) { - return code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z || - code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z; + return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || + (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z); } // Resolves . and .. elements in a path with directory names @@ -155,8 +155,8 @@ const win32 = { // Verify that a cwd was found and that it actually points // to our drive. If not, default to the drive's root. if (path === undefined || - path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() && - path.charCodeAt(2) === CHAR_BACKWARD_SLASH) { + (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() && + path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) { path = `${resolvedDevice}\\`; } } @@ -358,10 +358,10 @@ const win32 = { const code = path.charCodeAt(0); return isPathSeparator(code) || // Possible device root - len > 2 && + (len > 2 && isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON && - isPathSeparator(path.charCodeAt(2)); + isPathSeparator(path.charCodeAt(2))); }, join(...args) { diff --git a/lib/readline.js b/lib/readline.js index feffb5592b1b50..e7c5a04bb03eed 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -602,7 +602,7 @@ Interface.prototype._wordRight = function() { function charLengthLeft(str, i) { if (i <= 0) return 0; - if (i > 1 && str.codePointAt(i - 2) >= kUTF16SurrogateThreshold || + if ((i > 1 && str.codePointAt(i - 2) >= kUTF16SurrogateThreshold) || str.codePointAt(i - 1) >= kUTF16SurrogateThreshold) { return 2; } diff --git a/lib/url.js b/lib/url.js index 665bd436148819..7a268cd43868a9 100644 --- a/lib/url.js +++ b/lib/url.js @@ -765,13 +765,13 @@ Url.prototype.resolveObject = function resolveObject(relative) { const isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'); const isRelAbs = ( - relative.host || relative.pathname && relative.pathname.charAt(0) === '/' + relative.host || (relative.pathname && relative.pathname.charAt(0) === '/') ); var mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)); const removeAllDots = mustEndAbs; - var srcPath = result.pathname && result.pathname.split('/') || []; - const relPath = relative.pathname && relative.pathname.split('/') || []; + var srcPath = (result.pathname && result.pathname.split('/')) || []; + const relPath = (relative.pathname && relative.pathname.split('/')) || []; const noLeadingSlashes = result.protocol && !slashedProtocol.has(result.protocol); @@ -869,8 +869,8 @@ Url.prototype.resolveObject = function resolveObject(relative) { // then it must NOT get a trailing slash. var last = srcPath.slice(-1)[0]; const hasTrailingSlash = ( - (result.host || relative.host || srcPath.length > 1) && - (last === '.' || last === '..') || last === ''); + ((result.host || relative.host || srcPath.length > 1) && + (last === '.' || last === '..')) || last === ''); // Strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 diff --git a/lib/util.js b/lib/util.js index c54b1dba302b1e..5ac2516f738b83 100644 --- a/lib/util.js +++ b/lib/util.js @@ -94,7 +94,7 @@ function isFunction(arg) { function isPrimitive(arg) { return arg === null || - typeof arg !== 'object' && typeof arg !== 'function'; + (typeof arg !== 'object' && typeof arg !== 'function'); } function pad(n) {