Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 1x 1x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 1x 35x 35x 35x 35x 35x 5x 5x 5x 30x 39x 16x 6x 6x 2x 2x 2x 4x 6x 6x 16x 10x 10x 39x 15x 30x 30x 30x 30x 30x 14x 8x 3x 3x 3x 3x 3x 3x 3x 8x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 8x 6x 6x 6x 6x 30x 15x 30x 30x 1x 35x 43x 16x 16x 27x 17x 17x 17x 27x 14x 14x 43x 5x 5x 14x 14x 14x 14x 38x 24x 38x 9x 9x 9x 14x 5x 5x 38x 14x 14x | import { parse } from '@babel/parser' import MagicString from 'magic-string' import type { ParserPlugin } from '@babel/parser' import type { Identifier, Statement } from '@babel/types' import { resolveParserPlugins } from './script/context' export function rewriteDefault( input: string, as: string, parserPlugins?: ParserPlugin[], ): string { const ast = parse(input, { sourceType: 'module', plugins: resolveParserPlugins('js', parserPlugins), }).program.body const s = new MagicString(input) rewriteDefaultAST(ast, s, as) return s.toString() } /** * Utility for rewriting `export default` in a script block into a variable * declaration so that we can inject things into it */ export function rewriteDefaultAST( ast: Statement[], s: MagicString, as: string, ): void { if (!hasDefaultExport(ast)) { s.append(`\nconst ${as} = {}`) return } // if the script somehow still contains `default export`, it probably has // multi-line comments or template strings. fallback to a full parse. ast.forEach(node => { if (node.type === 'ExportDefaultDeclaration') { if (node.declaration.type === 'ClassDeclaration' && node.declaration.id) { let start: number = node.declaration.decorators && node.declaration.decorators.length > 0 ? node.declaration.decorators[ node.declaration.decorators.length - 1 ].end! : node.start! s.overwrite(start, node.declaration.id.start!, ` class `) s.append(`\nconst ${as} = ${node.declaration.id.name}`) } else { s.overwrite(node.start!, node.declaration.start!, `const ${as} = `) } } else if (node.type === 'ExportNamedDeclaration') { for (const specifier of node.specifiers) { if ( specifier.type === 'ExportSpecifier' && specifier.exported.type === 'Identifier' && specifier.exported.name === 'default' ) { if (node.source) { if (specifier.local.name === 'default') { s.prepend( `import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n`, ) const end = specifierEnd(s, specifier.local.end!, node.end!) s.remove(specifier.start!, end) s.append(`\nconst ${as} = __VUE_DEFAULT__`) continue } else { s.prepend( `import { ${s.slice( specifier.local.start!, specifier.local.end!, )} as __VUE_DEFAULT__ } from '${node.source.value}'\n`, ) const end = specifierEnd(s, specifier.exported.end!, node.end!) s.remove(specifier.start!, end) s.append(`\nconst ${as} = __VUE_DEFAULT__`) continue } } const end = specifierEnd(s, specifier.end!, node.end!) s.remove(specifier.start!, end) s.append(`\nconst ${as} = ${specifier.local.name}`) } } } }) } export function hasDefaultExport(ast: Statement[]): boolean { for (const stmt of ast) { if (stmt.type === 'ExportDefaultDeclaration') { return true } else if ( stmt.type === 'ExportNamedDeclaration' && stmt.specifiers.some( spec => (spec.exported as Identifier).name === 'default', ) ) { return true } } return false } function specifierEnd(s: MagicString, end: number, nodeEnd: number | null) { // export { default , foo } ... let hasCommas = false let oldEnd = end while (end < nodeEnd!) { if (/\s/.test(s.slice(end, end + 1))) { end++ } else if (s.slice(end, end + 1) === ',') { end++ hasCommas = true break } else if (s.slice(end, end + 1) === '}') { break } } return hasCommas ? end : oldEnd } |