{"version":3,"sources":["../src/index.ts","../src/enhancer.ts","../src/walk.ts","../src/transformer.ts"],"sourcesContent":["export { type EnhancedProgramResult, enhanceProgram, generateDecorators } from './enhancer'\nexport { transformFnDecoratorProgram } from './transformer'\nexport {\n  deepRemovePosition,\n  type DeepRemovePositionResult,\n  getPreviousNodes,\n  type Visitors,\n  deepWalk as walk,\n} from './walk'\n","import type { Decorator, Function, MagicString, Program } from 'oxc-parser'\nimport { parseSync } from 'oxc-parser'\nimport { deepWalk, getPreviousNodes } from './walk'\n\ndeclare module '@oxc-project/types' {\n  interface Function {\n    decorators: Array<Decorator>\n  }\n}\n\nexport interface EnhancedProgramResult {\n  program: Program\n  magicString: MagicString\n  onGenerateDecorators?: (decorators: Decorator[], node: Function) => void\n}\n\nexport function enhanceProgram<TResult extends EnhancedProgramResult>({ program, magicString, onGenerateDecorators, ...rest }: TResult): TResult {\n  const newProgram = program\n  deepWalk(newProgram, {\n    Function(node) {\n      const previousNodes = getPreviousNodes(node, program)\n      const lastPreviousNode = previousNodes[previousNodes.length - 1]\n      const text = magicString.getSourceText(lastPreviousNode ? lastPreviousNode.end : 0, node.start)\n      if (!text)\n        return\n      node.decorators = generateDecorators(text, lastPreviousNode ? lastPreviousNode.end : 0, node.start)\n      onGenerateDecorators?.(node.decorators, node)\n    },\n  })\n  return { program: newProgram, magicString, ...rest } as TResult\n}\n\nconst generateSpace = (length: number): string => ' '.repeat(length)\n\nexport function generateDecorators(text: string, decoratorsStart: number, _decoratorsEnd: number): Decorator[] {\n  const decorators: Decorator[] = []\n  // 使用正则表达式匹配装饰器\n  const decoratorPattern = /@\\w+(?:\\([^)]*\\))?/g\n  let match\n  // eslint-disable-next-line no-cond-assign\n  while ((match = decoratorPattern.exec(text)) !== null) {\n    const decoratorStart = decoratorsStart + match.index\n    const decoratorEnd = decoratorStart + match[0].length\n\n    // 生成space 这样就能得到对应的`start`和`end`\n    // slice 1即删掉`@`，因此generateSpace必须要 + 1，补回去一个space\n    const parseResult = parseSync('test.ts', generateSpace(decoratorStart + 1) + match[0].slice(1))\n    const expressionStatement = parseResult.program.body.find(node => node.type === 'ExpressionStatement')\n    if (!expressionStatement)\n      continue\n\n    decorators.push({\n      start: decoratorStart,\n      end: decoratorEnd,\n      type: 'Decorator',\n      expression: expressionStatement.expression,\n    })\n  }\n\n  return decorators\n}\n","import type { CallExpression, Class, ClassElement, Expression, Function, NewExpression, Program, Statement } from 'oxc-parser'\n\nexport type Node = Statement | Expression | ClassElement\n\nexport interface FunctionDeclaration extends Function {\n  type: 'FunctionDeclaration'\n}\n\nexport interface FunctionExpression extends Function {\n  type: 'FunctionExpression'\n}\n\nexport interface TSDeclareFunction extends Function {\n  type: 'TSDeclareFunction'\n}\n\nexport interface TSEmptyBodyFunctionExpression extends Function {\n  type: 'TSEmptyBodyFunctionExpression'\n}\n\nexport interface ClassDeclaration extends Class {\n  type: 'ClassDeclaration'\n}\n\nexport interface Visitors {\n  CallExpression?: (node: CallExpression, parent: Node[]) => void\n  FunctionDeclaration?: (node: FunctionDeclaration, parent: Node[]) => void\n  Function?: (node: Function, parent: Node[]) => void\n  FunctionExpression?: (node: FunctionExpression, parent: Node[]) => void\n  TSDeclareFunction?: (node: TSDeclareFunction, parent: Node[]) => void\n  TSEmptyBodyFunctionExpression?: (node: TSEmptyBodyFunctionExpression, parent: Node[]) => void\n  NewExpression?: (node: NewExpression, parent: Node[]) => void\n  ClassDeclaration?: (node: ClassDeclaration, parent: Node[]) => void\n  All?: (node: Node, parent: Node[]) => void\n}\n\nexport function deepWalk(node: Program, visitors: Visitors = {}): void {\n  function walk(walkNode: Statement | Expression | ClassElement, parent: Node[]): void {\n    if (walkNode.type === 'CallExpression') {\n      visitors.CallExpression?.(walkNode, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'FunctionDeclaration') {\n      visitors.FunctionDeclaration?.(walkNode as FunctionDeclaration, parent)\n      visitors.Function?.(walkNode as Function, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'FunctionExpression') {\n      visitors.FunctionExpression?.(walkNode as FunctionExpression, parent)\n      visitors.Function?.(walkNode as Function, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'TSDeclareFunction') {\n      visitors.TSDeclareFunction?.(walkNode as TSDeclareFunction, parent)\n      visitors.Function?.(walkNode as Function, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'TSEmptyBodyFunctionExpression') {\n      visitors.TSEmptyBodyFunctionExpression?.(walkNode as TSEmptyBodyFunctionExpression, parent)\n      visitors.Function?.(walkNode as Function, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'NewExpression') {\n      visitors.NewExpression?.(walkNode as NewExpression, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else if (walkNode.type === 'ClassDeclaration') {\n      visitors.ClassDeclaration?.(walkNode as ClassDeclaration, parent)\n      visitors.All?.(walkNode, parent)\n    }\n    else {\n      visitors.All?.(walkNode, parent)\n    }\n\n    // 遍历所有节点\n    for (const key in walkNode) {\n      const statement = (walkNode as any)[key]\n      if (typeof statement !== 'object' || statement === null)\n        continue\n\n      if (Array.isArray(statement)) {\n        for (const item of statement) {\n          walk(item, parent ? [...parent, walkNode] : [walkNode])\n        }\n      }\n      else if ('type' in statement && typeof statement.type === 'string') {\n        walk(statement, parent ? [...parent, walkNode] : [walkNode])\n      }\n    }\n  }\n\n  for (const statement of node.body) {\n    walk(statement, [])\n  }\n}\n\nexport type DeepRemovePositionResult<T extends Record<string, any>> = {\n  [K in keyof T as K extends 'start' | 'end' ? never : K]: DeepRemovePositionResult<T[K]>\n}\n\nexport function deepRemovePosition<T extends Record<string, any>>(node: Readonly<T>): DeepRemovePositionResult<T> {\n  const result: any = Array.isArray(node) ? [] : {}\n\n  for (const key in node) {\n    if (key === 'start' || key === 'end')\n      continue\n\n    const value = node[key]\n    result[key] = (typeof value === 'object' && value !== null) ? deepRemovePosition(value) : value\n  }\n\n  return result\n}\n\nexport function getPreviousNodes(compareNode: Statement | Expression | ClassElement, program: Program): Node[] {\n  const previousNodes: Node[] = []\n  let isEnded = false\n  deepWalk(program, {\n    All(node) {\n      if (isEnded)\n        return\n\n      if (node.start !== compareNode.start && node.end !== compareNode.end) {\n        previousNodes.push(node)\n      }\n      else {\n        isEnded = true\n      }\n    },\n  })\n\n  return previousNodes\n}\n","import type { TSType } from 'oxc-parser'\nimport type { EnhancedProgramResult } from './enhancer'\nimport MagicString from 'magic-string'\nimport { deepWalk } from './walk'\n\nexport interface TransformOptions {\n  metadata?: boolean\n}\n\nexport function transformFnDecoratorProgram<TResult extends EnhancedProgramResult>({ program, magicString }: TResult, options: TransformOptions = {}): MagicString {\n  const text = magicString.toString()\n  const newMagicString = new MagicString(text)\n\n  deepWalk(program, {\n    Function(node) {\n      if (!('decorators' in node) || !Array.isArray(node.decorators) || node.decorators.length === 0)\n        return\n      if (!node.id || !node.body)\n        return\n      if (node.type === 'TSDeclareFunction' || node.type === 'TSEmptyBodyFunctionExpression')\n        return\n\n      if (options && options.metadata !== false) {\n        const paramTypes = node.params.items.map((item) => {\n          if (item.type === 'FormalParameter') {\n            if (!item.pattern.typeAnnotation)\n              return 'Object'\n            return tsTypeToConstructor(\n              item.pattern.typeAnnotation.typeAnnotation,\n              newMagicString.slice(\n                item.pattern.typeAnnotation.typeAnnotation.start,\n                item.pattern.typeAnnotation.typeAnnotation.end,\n              ),\n            )\n          }\n          else if (item.type === 'RestElement') {\n            if (!item.typeAnnotation)\n              return 'Object'\n            return tsTypeToConstructor(\n              item.typeAnnotation.typeAnnotation,\n              newMagicString.slice(\n                item.typeAnnotation.typeAnnotation.start,\n                item.typeAnnotation.typeAnnotation.end,\n              ),\n            )\n          }\n          return 'Object'\n        }).join(', ')\n        newMagicString.appendRight(node.end, `\\nif (!${node.id.name}[Symbol.metadata]) ${node.id.name}[Symbol.metadata] = {};\\n${node.id.name}[Symbol.metadata]['design:paramtypes'] = [${paramTypes}];`)\n      }\n\n      for (const decorator of node.decorators) {\n        const decoratorText = newMagicString.slice(decorator.expression.start, decorator.expression.end)\n        newMagicString.appendRight(node.end, `\\n${decoratorText}(${node.id.name}, { kind: 'function', name: '${node.id.name}', metadata: ${node.id.name}[Symbol.metadata], addInitializer: (fn) => { if (!${node.id.name}['__initializer__']) ${node.id.name}['__initializer__'] = []; ${node.id.name}['__initializer__'].push(fn); } });`)\n      }\n\n      // Remove decorators\n      const firstDecorator = node.decorators[0]\n      const lastDecorator = node.decorators[node.decorators.length - 1]\n      newMagicString.remove(firstDecorator.start, lastDecorator.end)\n\n      // Add initializer\n      const firstStatement = node.body.statements[0]\n      newMagicString.appendRight(firstStatement ? firstStatement.start : node.body.start + 1, `\\n${newMagicString.getIndentString()}(${node.id.name}['__initializer__'] || []).map(i => i());\\n`)\n    },\n  })\n\n  return newMagicString\n}\n\nfunction getTryingText(id: string): string {\n  return `(() => { try { return typeof ${id} === 'undefined' ? Object : ${id} } catch (e) { return Object } })()`\n}\n\nfunction tsTypeToConstructor(typeNode: TSType, tryingId: string): string {\n  switch (typeNode.type) {\n    case 'TSStringKeyword':\n      return 'String'\n    case 'TSNumberKeyword':\n      return 'Number'\n    case 'TSBooleanKeyword':\n      return 'Boolean'\n    case 'TSNullKeyword':\n      return 'null'\n    case 'TSUndefinedKeyword':\n      return 'undefined'\n    case 'TSLiteralType':\n      return typeNode.literal.type === 'Literal' ? literalValueToConstructor(typeNode.literal.value) : getTryingText(tryingId)\n    case 'TSArrayType':\n      return `Array`\n    case 'TSTupleType':\n      return 'Array'\n    case 'TSBigIntKeyword':\n      return 'BigInt'\n    case 'TSSymbolKeyword':\n      return 'Symbol'\n    case 'TSTypeReference':\n      return getTryingText(tryingId)\n    default:\n      return 'Object'\n  }\n}\n\nfunction literalValueToConstructor(literal: unknown): string {\n  switch (typeof literal) {\n    case 'string':\n      return 'String'\n    case 'number':\n      return 'Number'\n    case 'boolean':\n      return 'Boolean'\n    case 'bigint':\n      return 'BigInt'\n    case 'undefined':\n      return 'undefined'\n    default:\n      return 'Object'\n  }\n}\n"],"mappings":"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","names":["MagicString"]}