1 line
18 KiB
Plaintext
1 line
18 KiB
Plaintext
{"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<(...args: unknown[]) => unknown>();\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: (...args: unknown[]) => unknown,\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 case \"()\":\n if (this.fnString.substr(this.pos, 2) === \"=>\") {\n return this.keyPrefix + this.fnString;\n }\n\n this.pos = offset;\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 tryParsePrefixTokens(): boolean {\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 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 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 multi-character operators\n * like '&&', are split into more than one token here. However, awareness of\n * some multi-character 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"]} |