Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbbreuer committed Nov 4, 2024
1 parent e234c8a commit aff343c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 47 deletions.
2 changes: 1 addition & 1 deletion fixtures/output/function.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export declare function fetchUsers(): Promise<ResponseData>;
export declare function getProduct(id: number): Promise<ApiResponse<Product>>;
export declare function authenticate(user: string, password: string): Promise<AuthResponse>;
export declare function dts(options?: DtsGenerationOption): BunPlugin;
export declare function loadConfig<T extends Record<string, unknown>>(): void;
export declare function loadConfig<T extends Record<string, unknown>>({ name, cwd, defaultConfig }: Options<T>): Promise<T>;
export declare function processData(data: string): string;
export declare function processData(data: number): number;
export declare function processData(data: boolean): boolean;
Expand Down
98 changes: 52 additions & 46 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ export function extractDtsTypes(sourceCode: string): string {
* // }
*/
function extractFunctionSignature(declaration: string): FunctionSignature {
// Get full declaration without early trimming
debugLog(undefined, 'signature-start', `Processing declaration: ${declaration}`)

// Get full declaration without early trimming to preserve structure
const cleanDeclaration = getCleanDeclaration(declaration)
debugLog(undefined, 'signature-clean', `Clean declaration: ${cleanDeclaration}`)

Expand All @@ -267,12 +269,12 @@ function extractFunctionSignature(declaration: string): FunctionSignature {

const name = functionMatch[1]
const contentAfterName = cleanDeclaration.slice(cleanDeclaration.indexOf(name) + name.length)
debugLog(undefined, 'signature-content', `Content after name: ${contentAfterName}`)

// Handle generics
let generics = ''
let rest = contentAfterName.trim()

// Extract complete generic block if it exists
if (rest.startsWith('<')) {
let depth = 0
let pos = 0
Expand All @@ -295,7 +297,9 @@ function extractFunctionSignature(declaration: string): FunctionSignature {
}
}

// Extract parameters
debugLog(undefined, 'signature-generics', `Extracted generics: ${generics}`)

// Extract parameters with improved destructuring support
let params = ''
if (rest.startsWith('(')) {
let depth = 0
Expand All @@ -319,6 +323,7 @@ function extractFunctionSignature(declaration: string): FunctionSignature {
}
}

// Track depth for all bracket types
if (!insideString) {
if (char === '(' || char === '{' || char === '<')
depth++
Expand All @@ -329,14 +334,17 @@ function extractFunctionSignature(declaration: string): FunctionSignature {
content.push(char)
pos = i

if (depth === 0 && content[0] === '(') {
params = content.join('').slice(1, -1).trim() // Remove outer parentheses
// Break when we find closing parenthesis at root level
if (depth === 0 && content[0] === '(' && char === ')') {
params = content.join('').slice(1, -1).trim()
rest = rest.slice(pos + 1).trim()
break
}
}
}

debugLog(undefined, 'signature-params', `Extracted params: ${params}`)

// Extract return type
let returnType = 'void'
if (rest.startsWith(':')) {
Expand All @@ -345,7 +353,7 @@ function extractFunctionSignature(declaration: string): FunctionSignature {
let insideString = false
let stringChar = ''

// Skip the colon
// Skip the colon and any whitespace
for (let i = 1; i < rest.length; i++) {
const char = rest[i]
const prevChar = rest[i - 1]
Expand Down Expand Up @@ -378,13 +386,9 @@ function extractFunctionSignature(declaration: string): FunctionSignature {
returnType = content.join('').trim()
}

debugLog(undefined, 'signature-parts', `
Name: ${name}
Generics: ${generics}
Params: ${params}
Return Type: ${returnType}
`)
debugLog(undefined, 'signature-return', `Extracted return type: ${returnType}`)

// Preserve parameter structure exactly as written
return {
name,
generics,
Expand Down Expand Up @@ -1672,46 +1676,48 @@ function processVariable(declaration: string, isExported: boolean, state: Proces
/**
* Process function declarations with overloads
*/
function processFunction(declaration: string, usedTypes?: Set<string>, isExported = true): string {
debugLog(undefined, 'process-function-start', `Starting to process: ${declaration}`)

const signature = extractFunctionSignature(declaration)
debugLog(undefined, 'process-function-signature', JSON.stringify(signature, null, 2))

// Build the declaration
const parts = [
isExported ? 'export ' : '',
'declare function ',
signature.name,
signature.generics,
`(${signature.params})`,
`: ${signature.returnType}`,
';',
]

const result = parts.filter(Boolean).join('')
debugLog(undefined, 'process-function-final', `Final declaration: ${result}`)
return result
}
function processFunction(declaration: string, usedTypes?: Set<string>, isExported = true): string {
debugLog(undefined, 'process-function-start', `Starting to process: ${declaration}`)

const signature = extractFunctionSignature(declaration)
debugLog(undefined, 'process-function-signature', JSON.stringify(signature, null, 2))

// Check if the function is async
const isAsync = declaration.includes('async function')
if (isAsync && !signature.returnType.includes('Promise')) {
signature.returnType = `Promise<${signature.returnType}>`
}

// Build the declaration preserving all parts exactly
const parts = [
isExported ? 'export ' : '',
'declare function ',
signature.name,
signature.generics,
`(${signature.params})`,
`: ${signature.returnType}`,
';',
]

const result = parts.filter(Boolean).join('')
debugLog(undefined, 'process-function-final', `Final declaration: ${result}`)
return result
}

function getCleanDeclaration(declaration: string): string {
// Split on the first { that isn't inside a type definition
let depth = 0
let pos = 0
// Remove leading comments while preserving the structure
const lines = declaration.split('\n')
let startIndex = 0

for (; pos < declaration.length; pos++) {
const char = declaration[pos]
if (char === '{') {
if (depth === 0 && declaration[pos - 1] !== ':') {
break
}
depth++
while (startIndex < lines.length) {
const line = lines[startIndex].trim()
if (!line.startsWith('//') && !line.startsWith('/*') && !line.startsWith('*') && line !== '') {
break
}
if (char === '}')
depth--
startIndex++
}

return declaration.slice(0, pos).trim()
return lines.slice(startIndex).join('\n').trim()
}

function processGeneratorFunction(declaration: string, state?: ProcessingState): string {
Expand Down

0 comments on commit aff343c

Please sign in to comment.