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 db1a261 commit 3b12b44
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
2 changes: 1 addition & 1 deletion fixtures/output/function.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ export declare function processData(data: unknown): unknown;
export declare function complexAsyncGenerator(): any;
export declare function isUser(value: unknown): value is User;
export declare function extractFunctionSignature(declaration: string): FunctionSignature;
export declare function createApi<T extends Record<string, (...args: any[]) => any>>(endpoints: T): { [K in keyof T]: ReturnType<T[K]> extends Promise<infer R> ? R : ReturnType<T[K]> } { return {} as any };
export declare function createApi<T extends Record<string, (...args: any[]) => any>>(endpoints: T): { [K in keyof T]: ReturnType<T[K]> extends Promise<infer R> ? R : ReturnType<T[K]> };
50 changes: 36 additions & 14 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,55 +422,77 @@ function extractParams(rest: string): { params: string, rest: string } {
function extractReturnType(rest: string, declaration: string): { returnType: string } {
let returnType = 'void'
if (rest.startsWith(':')) {
debugLog(undefined, 'signature-return-start', `Processing return type from: ${rest}`)
debugLog(undefined, 'return-start', `Starting return type extraction with: ${rest}`)
rest = rest.slice(1).trim()

if (!rest) {
// If rest is empty, perhaps the return type is on the next line(s)
const indexOfColon = declaration.indexOf(':')
rest = declaration.slice(indexOfColon + 1).trim()
}

let depth = 0
let buffer = ''
let i = 0
let inString = false
let stringChar = ''
let foundEnd = false

debugLog(undefined, 'return-extraction', 'Starting character-by-character extraction')

while (i < rest.length) {
while (i < rest.length && !foundEnd) {
const char = rest[i]
const prevChar = i > 0 ? rest[i - 1] : ''
const nextChar = i < rest.length - 1 ? rest[i + 1] : ''

// Handle string literals
debugLog(undefined, 'return-char',
`Pos ${i}: Char "${char}", Depth ${depth}, InString ${inString}, Buffer length ${buffer.length}`)

// Handle string boundaries
if ((char === '"' || char === '\'' || char === '`') && prevChar !== '\\') {
if (!inString) {
inString = true
stringChar = char
debugLog(undefined, 'return-string', `Entering string with ${stringChar}`)
}
else if (char === stringChar) {
inString = false
debugLog(undefined, 'return-string', 'Exiting string')
}
}

// Track depth when not in string
if (!inString) {
if (char === '{' || char === '<' || char === '(')
if (char === '{' || char === '<' || char === '(') {
depth++
else if (char === '}' || char === '>' || char === ')')
debugLog(undefined, 'return-depth', `Opening bracket, increasing depth to ${depth}`)
}
else if (char === '}' || char === '>' || char === ')') {
depth--
debugLog(undefined, 'return-depth', `Closing bracket, decreasing depth to ${depth}`)

// If we hit depth 0 with a closing brace, this might be the end of our type
if (depth === 0 && char === '}') {
buffer += char
// Look ahead to see if this is followed by a function body
const nextNonWhitespace = rest.slice(i + 1).trim()[0]
if (nextNonWhitespace === '{') {
debugLog(undefined, 'return-end', `Found end of return type at pos ${i}, next char is function body`)
foundEnd = true
break
}
}
}

// Stop at function body start or when we hit a semicolon outside any depth
if ((depth === 0 && char === '{') || (depth === 0 && char === ';')) {
// Stop at semicolons at depth 0
if (depth === 0 && char === ';') {
debugLog(undefined, 'return-end', 'Found semicolon at depth 0')
foundEnd = true
break
}
}

buffer += char
debugLog(undefined, 'return-buffer', `Updated buffer: ${buffer}`)
i++
}

returnType = buffer.trim()
debugLog(undefined, 'signature-return', `Extracted return type: ${returnType}`)
debugLog(undefined, 'return-final', `Final extracted return type: ${returnType}`)
}
return { returnType }
}
Expand Down

0 comments on commit 3b12b44

Please sign in to comment.