| 'use strict'; |
| |
| var fnToStr = Function.prototype.toString; |
| var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply; |
| var badArrayLike; |
| var isCallableMarker; |
| if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') { |
| try { |
| badArrayLike = Object.defineProperty({}, 'length', { |
| get: function () { |
| throw isCallableMarker; |
| } |
| }); |
| isCallableMarker = {}; |
| // eslint-disable-next-line no-throw-literal |
| reflectApply(function () { throw 42; }, null, badArrayLike); |
| } catch (_) { |
| if (_ !== isCallableMarker) { |
| reflectApply = null; |
| } |
| } |
| } else { |
| reflectApply = null; |
| } |
| |
| var constructorRegex = /^\s*class\b/; |
| var isES6ClassFn = function isES6ClassFunction(value) { |
| try { |
| var fnStr = fnToStr.call(value); |
| return constructorRegex.test(fnStr); |
| } catch (e) { |
| return false; // not a function |
| } |
| }; |
| |
| var tryFunctionObject = function tryFunctionToStr(value) { |
| try { |
| if (isES6ClassFn(value)) { return false; } |
| fnToStr.call(value); |
| return true; |
| } catch (e) { |
| return false; |
| } |
| }; |
| var toStr = Object.prototype.toString; |
| var fnClass = '[object Function]'; |
| var genClass = '[object GeneratorFunction]'; |
| var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; |
| |
| module.exports = reflectApply |
| ? function isCallable(value) { |
| if (!value) { return false; } |
| if (typeof value !== 'function' && typeof value !== 'object') { return false; } |
| if (typeof value === 'function' && !value.prototype) { return true; } |
| try { |
| reflectApply(value, null, badArrayLike); |
| } catch (e) { |
| if (e !== isCallableMarker) { return false; } |
| } |
| return !isES6ClassFn(value); |
| } |
| : function isCallable(value) { |
| if (!value) { return false; } |
| if (typeof value !== 'function' && typeof value !== 'object') { return false; } |
| if (typeof value === 'function' && !value.prototype) { return true; } |
| if (hasToStringTag) { return tryFunctionObject(value); } |
| if (isES6ClassFn(value)) { return false; } |
| var strClass = toStr.call(value); |
| return strClass === fnClass || strClass === genClass; |
| }; |