Skip to content

Commit

Permalink
lib: refactor internal/util
Browse files Browse the repository at this point in the history
* Use the more efficient module.exports = {} approach
* Eliminate some uses of arguments

PR-URL: #11404
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net
  • Loading branch information
jasnell committed Apr 21, 2017
1 parent 5e095f6 commit 9077b48
Showing 1 changed file with 50 additions and 37 deletions.
87 changes: 50 additions & 37 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ const signals = process.binding('constants').os.signals;

const kArrowMessagePrivateSymbolIndex = binding['arrow_message_private_symbol'];
const kDecoratedPrivateSymbolIndex = binding['decorated_private_symbol'];
const noCrypto = !process.versions.openssl;

// The `buffer` module uses this. Defining it here instead of in the public
// `util` module makes it accessible without having to `require('util')` there.
exports.customInspectSymbol = Symbol('util.inspect.custom');
function isError(e) {
return objectToString(e) === '[object Error]' || e instanceof Error;
}

function objectToString(o) {
return Object.prototype.toString.call(o);
}

// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function deprecate(fn, msg, code) {
function deprecate(fn, msg, code) {
// Allow for deprecating things in the process of starting up.
if (global.process === undefined) {
return function() {
return exports.deprecate(fn, msg, code).apply(this, arguments);
return function(...args) {
return deprecate(fn, msg).apply(this, args);
};
}

Expand All @@ -29,7 +34,7 @@ exports.deprecate = function deprecate(fn, msg, code) {
throw new TypeError('`code` argument must be a string');

var warned = false;
function deprecated() {
function deprecated(...args) {
if (!warned) {
warned = true;
if (code !== undefined) {
Expand All @@ -39,9 +44,9 @@ exports.deprecate = function deprecate(fn, msg, code) {
}
}
if (new.target) {
return Reflect.construct(fn, arguments, new.target);
return Reflect.construct(fn, args, new.target);
}
return fn.apply(this, arguments);
return fn.apply(this, args);
}

// The wrapper will keep the same prototype as fn to maintain prototype chain
Expand All @@ -54,10 +59,10 @@ exports.deprecate = function deprecate(fn, msg, code) {
}

return deprecated;
};
}

exports.decorateErrorStack = function decorateErrorStack(err) {
if (!(exports.isError(err) && err.stack) ||
function decorateErrorStack(err) {
if (!(isError(err) && err.stack) ||
binding.getHiddenValue(err, kDecoratedPrivateSymbolIndex) === true)
return;

Expand All @@ -67,30 +72,19 @@ exports.decorateErrorStack = function decorateErrorStack(err) {
err.stack = arrow + err.stack;
binding.setHiddenValue(err, kDecoratedPrivateSymbolIndex, true);
}
};

exports.isError = function isError(e) {
return exports.objectToString(e) === '[object Error]' || e instanceof Error;
};

exports.objectToString = function objectToString(o) {
return Object.prototype.toString.call(o);
};
}

const noCrypto = !process.versions.openssl;
exports.assertCrypto = function() {
function assertCrypto() {
if (noCrypto)
throw new Error('Node.js is not compiled with openssl crypto support');
};

exports.kIsEncodingSymbol = Symbol('node.isEncoding');
}

// The loop should only run at most twice, retrying with lowercased enc
// if there is no match in the first pass.
// We use a loop instead of branching to retry with a helper
// function in order to avoid the performance hit.
// Return undefined if there is no match.
exports.normalizeEncoding = function normalizeEncoding(enc) {
function normalizeEncoding(enc) {
if (!enc) return 'utf8';
var retried;
while (true) {
Expand All @@ -116,11 +110,9 @@ exports.normalizeEncoding = function normalizeEncoding(enc) {
retried = true;
}
}
};
}

// Filters duplicate strings. Used to support functions in crypto and tls
// modules. Implemented specifically to maintain existing behaviors in each.
exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) {
function filterDuplicateStrings(items, low) {
const map = new Map();
for (var i = 0; i < items.length; i++) {
const item = items[i];
Expand All @@ -132,24 +124,24 @@ exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) {
}
}
return Array.from(map.values()).sort();
};
}

exports.cachedResult = function cachedResult(fn) {
function cachedResult(fn) {
var result;
return () => {
if (result === undefined)
result = fn();
return result.slice();
};
};
}

// Useful for Wrapping an ES6 Class with a constructor Function that
// does not require the new keyword. For instance:
// class A { constructor(x) {this.x = x;}}
// const B = createClassWrapper(A);
// B() instanceof A // true
// B() instanceof B // true
exports.createClassWrapper = function createClassWrapper(type) {
function createClassWrapper(type) {
const fn = function(...args) {
return Reflect.construct(type, args, new.target || type);
};
Expand All @@ -161,7 +153,7 @@ exports.createClassWrapper = function createClassWrapper(type) {
Object.setPrototypeOf(fn, type);
fn.prototype = type.prototype;
return fn;
};
}

let signalsToNamesMapping;
function getSignalsToNamesMapping() {
Expand All @@ -176,7 +168,7 @@ function getSignalsToNamesMapping() {
return signalsToNamesMapping;
}

exports.convertToValidSignal = function convertToValidSignal(signal) {
function convertToValidSignal(signal) {
if (typeof signal === 'number' && getSignalsToNamesMapping()[signal])
return signal;

Expand All @@ -186,4 +178,25 @@ exports.convertToValidSignal = function convertToValidSignal(signal) {
}

throw new Error('Unknown signal: ' + signal);
}

module.exports = exports = {
assertCrypto,
cachedResult,
convertToValidSignal,
createClassWrapper,
decorateErrorStack,
deprecate,
filterDuplicateStrings,
isError,
normalizeEncoding,
objectToString,

// Symbol used to provide a custom inspect function for an object as an
// alternative to using 'inspect'
customInspectSymbol: Symbol('util.inspect.custom'),

// Used by the buffer module to capture an internal reference to the
// default isEncoding implementation, just in case userland overrides it.
kIsEncodingSymbol: Symbol('node.isEncoding')
};

0 comments on commit 9077b48

Please sign in to comment.