{"version":3,"file":"function.js","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"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","sourcesContent":["import { Next, ToString } from \"./types\";\nimport { quoteKey, isValidVariableName } from \"./quote\";\n\n/**\n * Used in function stringification.\n */\n/* istanbul ignore next */\nconst METHOD_NAMES_ARE_QUOTED =\n  {\n    \" \"() {\n      /* Empty. */\n    }\n  }[\" \"]\n    .toString()\n    .charAt(0) === '\"';\n\nconst FUNCTION_PREFIXES = {\n  Function: \"function \",\n  GeneratorFunction: \"function* \",\n  AsyncFunction: \"async function \",\n  AsyncGeneratorFunction: \"async function* \"\n};\n\nconst METHOD_PREFIXES = {\n  Function: \"\",\n  GeneratorFunction: \"*\",\n  AsyncFunction: \"async \",\n  AsyncGeneratorFunction: \"async *\"\n};\n\nconst TOKENS_PRECEDING_REGEXPS = new Set(\n  (\n    \"case delete else in instanceof new return throw typeof void \" +\n    \", ; : + - ! ~ & | ^ * / % < > ? =\"\n  ).split(\" \")\n);\n\n/**\n * Track function parser usage.\n */\nexport const USED_METHOD_KEY = new WeakSet<Function>();\n\n/**\n * Stringify a function.\n */\nexport const functionToString: ToString = (fn, space, next, key) => {\n  const name = typeof key === \"string\" ? key : undefined;\n\n  // Track in function parser for object stringify to avoid duplicate output.\n  if (name !== undefined) USED_METHOD_KEY.add(fn);\n\n  return new FunctionParser(fn, space, next, name).stringify();\n};\n\n/**\n * Rewrite a stringified function to remove initial indentation.\n */\nexport function dedentFunction(fnString: string) {\n  let found: string | undefined;\n\n  for (const line of fnString.split(\"\\n\").slice(1)) {\n    const m = /^[\\s\\t]+/.exec(line);\n    if (!m) return fnString; // Early exit without indent.\n\n    const [str] = m;\n\n    if (found === undefined) found = str;\n    else if (str.length < found.length) found = str;\n  }\n\n  return found ? fnString.split(`\\n${found}`).join(\"\\n\") : fnString;\n}\n\n/**\n * Function parser and stringify.\n */\nexport class FunctionParser {\n  fnString: string;\n  fnType: keyof typeof FUNCTION_PREFIXES;\n  keyQuote: string | undefined;\n  keyPrefix: string;\n  isMethodCandidate: boolean;\n\n  pos = 0;\n  hadKeyword = false;\n\n  constructor(\n    public fn: Function,\n    public indent: string,\n    public next: Next,\n    public key?: string\n  ) {\n    this.fnString = Function.prototype.toString.call(fn);\n    this.fnType = fn.constructor.name as keyof typeof FUNCTION_PREFIXES;\n    this.keyQuote = key === undefined ? \"\" : quoteKey(key, next);\n    this.keyPrefix =\n      key === undefined ? \"\" : `${this.keyQuote}:${indent ? \" \" : \"\"}`;\n    this.isMethodCandidate =\n      key === undefined ? false : this.fn.name === \"\" || this.fn.name === key;\n  }\n\n  stringify() {\n    const value = this.tryParse();\n\n    // If we can't stringify this function, return a void expression; for\n    // bonus help with debugging, include the function as a string literal.\n    if (!value) {\n      return `${this.keyPrefix}void ${this.next(this.fnString)}`;\n    }\n\n    return dedentFunction(value);\n  }\n\n  getPrefix() {\n    if (this.isMethodCandidate && !this.hadKeyword) {\n      return METHOD_PREFIXES[this.fnType] + this.keyQuote;\n    }\n\n    return this.keyPrefix + FUNCTION_PREFIXES[this.fnType];\n  }\n\n  tryParse() {\n    if (this.fnString[this.fnString.length - 1] !== \"}\") {\n      // Must be an arrow function.\n      return this.keyPrefix + this.fnString;\n    }\n\n    // Attempt to remove function prefix.\n    if (this.fn.name) {\n      const result = this.tryStrippingName();\n      if (result) return result;\n    }\n\n    // Support class expressions.\n    const prevPos = this.pos;\n    if (this.consumeSyntax() === \"class\") return this.fnString;\n    this.pos = prevPos;\n\n    if (this.tryParsePrefixTokens()) {\n      const result = this.tryStrippingName();\n      if (result) return result;\n\n      let offset = this.pos;\n\n      switch (this.consumeSyntax(\"WORD_LIKE\")) {\n        case \"WORD_LIKE\":\n          if (this.isMethodCandidate && !this.hadKeyword) {\n            offset = this.pos;\n          }\n        // tslint:disable-next-line no-switch-case-fall-through\n        case \"()\":\n          if (this.fnString.substr(this.pos, 2) === \"=>\") {\n            return this.keyPrefix + this.fnString;\n          }\n\n          this.pos = offset;\n        // tslint:disable-next-line no-switch-case-fall-through\n        case '\"':\n        case \"'\":\n        case \"[]\":\n          return this.getPrefix() + this.fnString.substr(this.pos);\n      }\n    }\n  }\n\n  /**\n   * Attempt to parse the function from the current position by first stripping\n   * the function's name from the front. This is not a fool-proof method on all\n   * JavaScript engines, but yields good results on Node.js 4 (and slightly\n   * less good results on Node.js 6 and 8).\n   */\n  tryStrippingName() {\n    if (METHOD_NAMES_ARE_QUOTED) {\n      // ... then this approach is unnecessary and yields false positives.\n      return;\n    }\n\n    let start = this.pos;\n    const prefix = this.fnString.substr(this.pos, this.fn.name.length);\n\n    if (prefix === this.fn.name) {\n      this.pos += prefix.length;\n\n      if (\n        this.consumeSyntax() === \"()\" &&\n        this.consumeSyntax() === \"{}\" &&\n        this.pos === this.fnString.length\n      ) {\n        // Don't include the function's name if it will be included in the\n        // prefix, or if it's invalid as a name in a function expression.\n        if (this.isMethodCandidate || !isValidVariableName(prefix)) {\n          start += prefix.length;\n        }\n\n        return this.getPrefix() + this.fnString.substr(start);\n      }\n    }\n\n    this.pos = start;\n  }\n\n  /**\n   * Attempt to advance the parser past the keywords expected to be at the\n   * start of this function's definition. This method sets `this.hadKeyword`\n   * based on whether or not a `function` keyword is consumed.\n   *\n   * @return {boolean}\n   */\n  tryParsePrefixTokens() {\n    let posPrev = this.pos;\n\n    this.hadKeyword = false;\n\n    switch (this.fnType) {\n      case \"AsyncFunction\":\n        if (this.consumeSyntax() !== \"async\") return false;\n\n        posPrev = this.pos;\n      // tslint:disable-next-line no-switch-case-fall-through\n      case \"Function\":\n        if (this.consumeSyntax() === \"function\") {\n          this.hadKeyword = true;\n        } else {\n          this.pos = posPrev;\n        }\n        return true;\n      case \"AsyncGeneratorFunction\":\n        if (this.consumeSyntax() !== \"async\") return false;\n      // tslint:disable-next-line no-switch-case-fall-through\n      case \"GeneratorFunction\":\n        let token = this.consumeSyntax();\n\n        if (token === \"function\") {\n          token = this.consumeSyntax();\n          this.hadKeyword = true;\n        }\n\n        return token === \"*\";\n    }\n  }\n\n  /**\n   * Advance the parser past one element of JavaScript syntax. This could be a\n   * matched pair of delimiters, like braces or parentheses, or an atomic unit\n   * like a keyword, variable, or operator. Return a normalized string\n   * representation of the element parsed--for example, returns '{}' for a\n   * matched pair of braces. Comments and whitespace are skipped.\n   *\n   * (This isn't a full parser, so the token scanning logic used here is as\n   * simple as it can be. As a consequence, some things that are one token in\n   * JavaScript, like decimal number literals or most multicharacter operators\n   * like '&&', are split into more than one token here. However, awareness of\n   * some multicharacter sequences like '=>' is necessary, so we match the few\n   * of them that we care about.)\n   */\n  consumeSyntax(wordLikeToken?: string) {\n    const m = this.consumeMatch(\n      /^(?:([A-Za-z_0-9$\\xA0-\\uFFFF]+)|=>|\\+\\+|\\-\\-|.)/\n    );\n\n    if (!m) return;\n\n    const [token, match] = m;\n    this.consumeWhitespace();\n\n    if (match) return wordLikeToken || match;\n\n    switch (token) {\n      case \"(\":\n        return this.consumeSyntaxUntil(\"(\", \")\");\n      case \"[\":\n        return this.consumeSyntaxUntil(\"[\", \"]\");\n      case \"{\":\n        return this.consumeSyntaxUntil(\"{\", \"}\");\n      case \"`\":\n        return this.consumeTemplate();\n      case '\"':\n        return this.consumeRegExp(/^(?:[^\\\\\"]|\\\\.)*\"/, '\"');\n      case \"'\":\n        return this.consumeRegExp(/^(?:[^\\\\']|\\\\.)*'/, \"'\");\n    }\n\n    return token;\n  }\n\n  consumeSyntaxUntil(startToken: string, endToken: string): string | undefined {\n    let isRegExpAllowed = true;\n\n    for (;;) {\n      const token = this.consumeSyntax();\n      if (token === endToken) return startToken + endToken;\n      if (!token || token === \")\" || token === \"]\" || token === \"}\") return;\n\n      if (\n        token === \"/\" &&\n        isRegExpAllowed &&\n        this.consumeMatch(/^(?:\\\\.|[^\\\\\\/\\n[]|\\[(?:\\\\.|[^\\]])*\\])+\\/[a-z]*/)\n      ) {\n        isRegExpAllowed = false;\n        this.consumeWhitespace();\n      } else {\n        isRegExpAllowed = TOKENS_PRECEDING_REGEXPS.has(token);\n      }\n    }\n  }\n\n  consumeMatch(re: RegExp) {\n    const m = re.exec(this.fnString.substr(this.pos));\n    if (m) this.pos += m[0].length;\n    return m;\n  }\n\n  /**\n   * Advance the parser past an arbitrary regular expression. Return `token`,\n   * or the match object of the regexp.\n   */\n  consumeRegExp(re: RegExp, token: string): string | undefined {\n    const m = re.exec(this.fnString.substr(this.pos));\n    if (!m) return;\n    this.pos += m[0].length;\n    this.consumeWhitespace();\n    return token;\n  }\n\n  /**\n   * Advance the parser past a template string.\n   */\n  consumeTemplate() {\n    for (;;) {\n      this.consumeMatch(/^(?:[^`$\\\\]|\\\\.|\\$(?!{))*/);\n\n      if (this.fnString[this.pos] === \"`\") {\n        this.pos++;\n        this.consumeWhitespace();\n        return \"`\";\n      }\n\n      if (this.fnString.substr(this.pos, 2) === \"${\") {\n        this.pos += 2;\n        this.consumeWhitespace();\n\n        if (this.consumeSyntaxUntil(\"{\", \"}\")) continue;\n      }\n\n      return;\n    }\n  }\n\n  /**\n   * Advance the parser past any whitespace or comments.\n   */\n  consumeWhitespace() {\n    this.consumeMatch(/^(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/);\n  }\n}\n"]}