| 'use strict'; |
| exports.onDeclarationExportError = undefined; |
| exports.onDeclarationExportParse = undefined; |
| const { parseDestructuring, parseFrom, parseIdentifier, parseWith } = require('./partParsers.cjs'); |
| const { addError, getPosition, stripComments } = require('./utils.cjs'); |
| /** |
| * Adds error of parsing `export` statement with declaration. |
| */ |
| const onDeclarationExportError = exports.onDeclarationExportError = (importsExports, _source, { start, end }) => addError(importsExports, 'Cannot find end of export with declaration', start, end); |
| /** |
| * Parses `export` statement with declaration. |
| */ |
| const onDeclarationExportParse = exports.onDeclarationExportParse = (importsExports, source, { start, end: unparsedStart, comments }, { start: unparsedEnd, end: exportEnd, match: endMatch }) => { |
| var end = exportEnd; |
| var isDeclare = false; |
| var isType = false; |
| var unparsed = stripComments(source, unparsedStart, unparsedEnd, comments).trim(); |
| if (unparsed.startsWith('declare ')) { |
| isDeclare = true; |
| unparsed = unparsed.slice(8).trim(); |
| } |
| if (unparsed.startsWith('type ')) { |
| isType = true; |
| unparsed = unparsed.slice(5).trim(); |
| } |
| const modifiers = `${isDeclare ? 'declare ' : ''}${isType ? 'type ' : ''}`; |
| if (unparsed[0] === '*') { |
| if (isDeclare) { |
| return addError(importsExports, `Cannot declare star export (\`export ${modifiers}* ... from ...\`)`, start, end); |
| } |
| let namespace; |
| if (unparsed.startsWith('* as ')) { |
| unparsed = unparsed.slice(5).trim(); |
| const spaceIndex = unparsed.indexOf(' '); |
| if (spaceIndex === -1) { |
| return addError(importsExports, `Cannot find namespace of \`export ${modifiers}* as ... from ...\` statement`, start, end); |
| } |
| namespace = unparsed.slice(0, spaceIndex); |
| unparsed = unparsed.slice(spaceIndex + 1); |
| } |
| if (unparsed[unparsed.length - 1] === ';') { |
| unparsed = unparsed.slice(0, -1).trim(); |
| } |
| const { groups } = endMatch; |
| let quoteCharacter; |
| if (groups.with === undefined) { |
| quoteCharacter = unparsed[unparsed.length - 1]; |
| unparsed = unparsed.slice(0, -1); |
| } |
| else { |
| quoteCharacter = groups.with[0]; |
| } |
| const reexportKind = `${namespace === undefined ? 'star' : 'namespace'} reexport`; |
| if (quoteCharacter !== "'" && quoteCharacter !== '"') { |
| return addError(importsExports, `Cannot find end of \`from\` string literal of ${reexportKind}`, start, end); |
| } |
| const { from, index } = parseFrom(quoteCharacter, unparsed); |
| if (index === -1) { |
| return addError(importsExports, `Cannot find start of \`from\` string literal of ${reexportKind}`, start, end); |
| } |
| let withAttributes; |
| if (groups.with !== undefined) { |
| if (isType) { |
| return addError(importsExports, `Cannot use import attributes (\`with {...}\`) in \`export ${modifiers}\` statement for ${reexportKind} from \`${from}\``, start, end); |
| } |
| const attributes = parseWith(exportEnd, source); |
| if (attributes === undefined) { |
| return addError(importsExports, `Cannot find end of import attributes (\`with {...}\`) for ${reexportKind} from \`${from}\``, start, end); |
| } |
| end = attributes.endIndex; |
| withAttributes = attributes.with; |
| if (withAttributes === undefined) { |
| return addError(importsExports, `Cannot parse import attributes (\`with {...}\`) for ${reexportKind} from \`${from}\``, start, end); |
| } |
| } |
| const position = getPosition(importsExports, start, end); |
| const parsedReexport = withAttributes === undefined ? position : { ...position, with: withAttributes }; |
| let key = 'starReexports'; |
| if (namespace !== undefined) { |
| parsedReexport.namespace = namespace; |
| key = 'namespaceReexports'; |
| } |
| if (isType) { |
| key = key === 'starReexports' ? 'typeStarReexports' : 'typeNamespaceReexports'; |
| } |
| let reexports = importsExports[key]; |
| reexports !== null && reexports !== void 0 ? reexports : (reexports = importsExports[key] = { __proto__: null }); |
| let reexportsList = reexports[from]; |
| if (reexportsList === undefined) { |
| reexports[from] = [parsedReexport]; |
| } |
| else { |
| reexportsList.push(parsedReexport); |
| } |
| return end; |
| } |
| const identifierIndex = parseIdentifier(unparsed); |
| if (identifierIndex === 0) { |
| return addError(importsExports, `Cannot parse declaration identifier of \`export ${modifiers}...\` statement`, start, end); |
| } |
| const identifier = unparsed.slice(0, identifierIndex); |
| if (isType) { |
| let { typeExports } = importsExports; |
| if (typeExports === undefined) { |
| importsExports.typeExports = typeExports = { __proto__: null }; |
| } |
| else if (identifier in typeExports) { |
| return addError(importsExports, `Duplicate exported type \`${identifier}\``, start, end); |
| } |
| typeExports[identifier] = getPosition(importsExports, start, end); |
| if (isDeclare) { |
| typeExports[identifier].isDeclare = true; |
| } |
| return; |
| } |
| if (identifier === 'default') { |
| if (isDeclare) { |
| return addError(importsExports, `Cannot export default with declare (\`export ${modifiers}default ...\`)`, start, end); |
| } |
| if (importsExports.defaultExport !== undefined) { |
| return addError(importsExports, 'Duplicate default export', start, end); |
| } |
| importsExports.defaultExport = getPosition(importsExports, start, end); |
| return; |
| } |
| unparsed = unparsed.slice(identifierIndex).trim(); |
| if (identifier === 'interface') { |
| const nameIndex = parseIdentifier(unparsed); |
| if (nameIndex === 0) { |
| return addError(importsExports, `Cannot parse interface identifier of \`export ${modifiers}interface ...\` statement`, start, end); |
| } |
| const name = unparsed.slice(0, nameIndex); |
| let { interfaceExports } = importsExports; |
| interfaceExports !== null && interfaceExports !== void 0 ? interfaceExports : (interfaceExports = importsExports.interfaceExports = { __proto__: null }); |
| const interfaceExport = getPosition(importsExports, start, end); |
| if (isDeclare) { |
| interfaceExport.isDeclare = true; |
| } |
| let exportsList = interfaceExports[name]; |
| if (exportsList === undefined) { |
| interfaceExports[name] = [interfaceExport]; |
| } |
| else { |
| exportsList.push(interfaceExport); |
| } |
| return; |
| } |
| if (identifier === 'namespace') { |
| const nameIndex = parseIdentifier(unparsed); |
| if (nameIndex === 0) { |
| return addError(importsExports, `Cannot parse namespace identifier of \`export ${modifiers}namespace ...\` statement`, start, end); |
| } |
| const name = unparsed.slice(0, nameIndex); |
| let { namespaceExports } = importsExports; |
| namespaceExports !== null && namespaceExports !== void 0 ? namespaceExports : (namespaceExports = importsExports.namespaceExports = { __proto__: null }); |
| const namespaceExport = getPosition(importsExports, start, end); |
| if (isDeclare) { |
| namespaceExport.isDeclare = true; |
| } |
| let exportsList = namespaceExports[name]; |
| if (exportsList === undefined) { |
| namespaceExports[name] = [namespaceExport]; |
| } |
| else { |
| exportsList.push(namespaceExport); |
| } |
| return; |
| } |
| var isAsync = false; |
| var kind; |
| const names = []; |
| switch (identifier) { |
| case 'const': |
| case 'class': |
| case 'enum': |
| case 'let': |
| case 'var': |
| if ((identifier === 'const' || identifier === 'let' || identifier === 'var') && |
| (unparsed[0] === '{' || unparsed[0] === '[')) { |
| const destructuring = parseDestructuring(unparsed + source.slice(end)); |
| if (destructuring === undefined) { |
| return addError(importsExports, `Cannot parse destructuring names in \`export ${modifiers}${identifier} ...\` statement`, start, end); |
| } |
| const endDiff = destructuring.endIndex - unparsed.length; |
| if (endDiff > 0) { |
| end += endDiff; |
| } |
| names.push(...destructuring.names); |
| kind = `destructuring ${identifier}`; |
| if (isDeclare) { |
| kind = `declare ${kind}`; |
| } |
| break; |
| } |
| const nameIndex = parseIdentifier(unparsed); |
| if (nameIndex === 0) { |
| return addError(importsExports, `Cannot parse \`${identifier}\` identifier of \`export ${modifiers}${identifier} ...\` statement`, start, end); |
| } |
| kind = identifier; |
| if (isDeclare) { |
| kind = `declare ${kind}`; |
| } |
| names[0] = unparsed.slice(0, nameIndex); |
| if (identifier === 'const' && names[0] === 'enum') { |
| unparsed = unparsed.slice(4).trim(); |
| const constEnumNameIndex = parseIdentifier(unparsed); |
| if (constEnumNameIndex === 0) { |
| return addError(importsExports, `Cannot parse identifier of \`export ${modifiers}const enum ...\` statement`, start, end); |
| } |
| kind = 'const enum'; |
| if (isDeclare) { |
| kind = `declare ${kind}`; |
| } |
| names[0] = unparsed.slice(0, constEnumNameIndex); |
| } |
| break; |
| case 'abstract': |
| if (!unparsed.startsWith('class ')) { |
| return addError(importsExports, `Cannot parse declaration of abstract class of \`export ${modifiers}abstract ...\` statement`, start, end); |
| } |
| unparsed = unparsed.slice(5).trim(); |
| const abstractClassNameIndex = parseIdentifier(unparsed); |
| if (abstractClassNameIndex === 0) { |
| return addError(importsExports, `Cannot parse \`${identifier}\` identifier of \`export ${modifiers}abstract class ${identifier} ...\` statement`, start, end); |
| } |
| kind = 'abstract class'; |
| if (isDeclare) { |
| kind = `declare ${kind}`; |
| } |
| names[0] = unparsed.slice(0, abstractClassNameIndex); |
| break; |
| // @ts-expect-error |
| case 'async': |
| if (isDeclare) { |
| return addError(importsExports, `Cannot export async function with declare (\`export ${modifiers}async ...\`)`, start, end); |
| } |
| if (unparsed.startsWith('function') === false) { |
| return addError(importsExports, 'Cannot parse async function in `export async ...` statement', start, end); |
| } |
| isAsync = true; |
| unparsed = unparsed.slice(8).trim(); |
| case 'function': |
| if (unparsed[0] === '*') { |
| if (isDeclare) { |
| return addError(importsExports, `Cannot export generator function with declare (\`export ${modifiers}function* ...\`)`, start, end); |
| } |
| unparsed = unparsed.slice(1).trim(); |
| kind = 'function*'; |
| } |
| else { |
| kind = 'function'; |
| } |
| if (isAsync) { |
| kind = `async ${kind}`; |
| } |
| else if (isDeclare) { |
| kind = 'declare function'; |
| } |
| const functionNameIndex = parseIdentifier(unparsed); |
| if (functionNameIndex === 0) { |
| return addError(importsExports, `Cannot parse \`${kind}\` identifier of \`export ${modifiers}${kind} ...\` statement`, start, end); |
| } |
| names[0] = unparsed.slice(0, functionNameIndex); |
| break; |
| default: |
| return addError(importsExports, `Cannot parse \`export ${modifiers}${identifier} ...\` statement`, start, end); |
| } |
| var { declarationExports } = importsExports; |
| declarationExports !== null && declarationExports !== void 0 ? declarationExports : (declarationExports = importsExports.declarationExports = { |
| __proto__: null, |
| }); |
| for (const name of names) { |
| if (name in declarationExports) { |
| return addError(importsExports, `Duplicate exported declaration \`${kind} ${name}\``, start, end); |
| } |
| declarationExports[name] = { |
| ...getPosition(importsExports, start, end), |
| kind: kind, |
| }; |
| } |
| return end; |
| }; |