index.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. 'use strict';
  2. var callBound = require('call-bound');
  3. var safeRegexTest = require('safe-regex-test');
  4. var isFnRegex = safeRegexTest(/^\s*(?:function)?\*/);
  5. var hasToStringTag = require('has-tostringtag/shams')();
  6. var getProto = require('get-proto');
  7. var toStr = callBound('Object.prototype.toString');
  8. var fnToStr = callBound('Function.prototype.toString');
  9. var getGeneratorFunc = function () { // eslint-disable-line consistent-return
  10. if (!hasToStringTag) {
  11. return false;
  12. }
  13. try {
  14. return Function('return function*() {}')();
  15. } catch (e) {
  16. }
  17. };
  18. /** @type {undefined | false | null | GeneratorFunctionConstructor} */
  19. var GeneratorFunction;
  20. /** @type {import('.')} */
  21. module.exports = function isGeneratorFunction(fn) {
  22. if (typeof fn !== 'function') {
  23. return false;
  24. }
  25. if (isFnRegex(fnToStr(fn))) {
  26. return true;
  27. }
  28. if (!hasToStringTag) {
  29. var str = toStr(fn);
  30. return str === '[object GeneratorFunction]';
  31. }
  32. if (!getProto) {
  33. return false;
  34. }
  35. if (typeof GeneratorFunction === 'undefined') {
  36. var generatorFunc = getGeneratorFunc();
  37. GeneratorFunction = generatorFunc
  38. // eslint-disable-next-line no-extra-parens
  39. ? /** @type {GeneratorFunctionConstructor} */ (getProto(generatorFunc))
  40. : false;
  41. }
  42. return getProto(fn) === GeneratorFunction;
  43. };