@@ -618,8 +618,10 @@ export function parseFunctionDeclaration(declaration: string): FunctionParseStat
618618 isAsync : false ,
619619 }
620620
621- // Check for async and clean declaration
621+ // Check for async
622622 state . isAsync = declaration . includes ( 'async' )
623+
624+ // Clean declaration
623625 let cleanDeclaration = declaration
624626 . replace ( / ^ e x p o r t \s + / , '' )
625627 . replace ( / ^ a s y n c \s + / , '' )
@@ -636,63 +638,26 @@ export function parseFunctionDeclaration(declaration: string): FunctionParseStat
636638 cleanDeclaration = cleanDeclaration . slice ( functionMatch [ 0 ] . length ) . trim ( )
637639 }
638640
639- // Extract full parameter string by matching balanced parentheses
640- let paramDepth = 0
641- let paramStart = - 1
642- let paramEnd = - 1
643- let inGeneric = false
644-
645- for ( let i = 0 ; i < cleanDeclaration . length ; i ++ ) {
646- const char = cleanDeclaration [ i ]
647- if ( char === '<' ) {
648- inGeneric = true
649- }
650- else if ( char === '>' ) {
651- inGeneric = false
652- }
653- else if ( ! inGeneric ) {
654- if ( char === '(' ) {
655- if ( paramDepth === 0 )
656- paramStart = i
657- paramDepth ++
658- }
659- else if ( char === ')' ) {
660- paramDepth --
661- if ( paramDepth === 0 ) {
662- paramEnd = i
663- break
664- }
665- }
666- }
641+ // Extract parameters
642+ const paramsMatch = cleanDeclaration . match ( / \( ( [ \s \S ] * ?) \) / )
643+ if ( paramsMatch ) {
644+ state . parameters = paramsMatch [ 1 ] . trim ( )
645+ cleanDeclaration = cleanDeclaration . slice ( paramsMatch [ 0 ] . length ) . trim ( )
667646 }
668647
669- if ( paramStart !== - 1 && paramEnd !== - 1 ) {
670- state . parameters = cleanDeclaration . slice ( paramStart + 1 , paramEnd ) . trim ( )
671- cleanDeclaration = cleanDeclaration . slice ( paramEnd + 1 ) . trim ( )
672- }
648+ // Extract return type, removing any duplicate colons
649+ if ( cleanDeclaration . startsWith ( ':' ) ) {
650+ let returnType = cleanDeclaration . slice ( 1 ) . trim ( )
651+ returnType = returnType
652+ . replace ( / : \s * $ / , '' ) // Remove trailing colons
653+ . replace ( / \s + / g, ' ' ) // Normalize spaces
654+ . trim ( )
673655
674- // Extract return type, handling Promise types correctly
675- // eslint-disable-next-line regexp/no-super-linear-backtracking
676- const returnMatch = cleanDeclaration . match ( / ^ : \s * ( .+ ?) (?: $ | \{ ) / )
677- if ( returnMatch ) {
678- let returnType = returnMatch [ 1 ] . trim ( )
679- . replace ( / ; $ / , '' )
680- . replace ( / \s + / g, ' ' )
681-
682- // Parse Promise return types
683- if ( returnType . includes ( 'Promise' ) ) {
684- const promiseMatch = returnType . match ( / P r o m i s e \s * < ( .+ ) > / )
685- if ( promiseMatch ) {
686- returnType = `Promise<${ promiseMatch [ 1 ] . trim ( ) } >`
687- }
688- else {
689- // If Promise is specified without type parameter, try to infer it
690- const typeParam = returnType . replace ( 'Promise' , '' ) . trim ( )
691- returnType = typeParam ? `Promise<${ typeParam } >` : 'Promise<void>'
692- }
656+ // Match the return type up to any trailing colon
657+ const returnMatch = returnType . match ( / ^ ( [ ^ : ] + ) / )
658+ if ( returnMatch ) {
659+ state . returnType = returnMatch [ 1 ] . trim ( )
693660 }
694-
695- state . returnType = returnType
696661 }
697662
698663 return state
@@ -792,6 +757,64 @@ export function processTypeDeclaration(declaration: string, isExported = true):
792757 return `${ isExported ? 'export ' : '' } declare type ${ typeName } = ${ typeBody } ;`
793758}
794759
760+ /**
761+ * Extract complete function signature handling multi-line declarations
762+ */
763+ export function extractFunctionSignature ( declaration : string ) : string {
764+ // First, normalize line breaks and whitespace
765+ const normalized = declaration
766+ . split ( '\n' )
767+ . map ( line => line . trim ( ) )
768+ . join ( ' ' )
769+
770+ // Match function declaration including parameters and return type
771+ const match = normalized . match ( / ^ ( e x p o r t \s + ) ? ( a s y n c \s + ) ? f u n c t i o n \s + ( [ ^ { ] + ) / )
772+ if ( ! match )
773+ return ''
774+
775+ let signature = match [ 0 ]
776+ let depth = 0
777+ let genericDepth = 0
778+ let foundBody = false
779+
780+ // Process character by character to find the complete signature
781+ for ( let i = match [ 0 ] . length ; i < normalized . length && ! foundBody ; i ++ ) {
782+ const char = normalized [ i ]
783+
784+ if ( char === '<' ) {
785+ genericDepth ++
786+ }
787+ else if ( char === '>' ) {
788+ genericDepth --
789+ }
790+ else if ( genericDepth === 0 ) {
791+ if ( char === '(' ) {
792+ depth ++
793+ }
794+ else if ( char === ')' ) {
795+ depth --
796+ }
797+ else if ( char === '{' ) {
798+ foundBody = true
799+ break
800+ }
801+ }
802+
803+ if ( ! foundBody ) {
804+ signature += char
805+ }
806+ }
807+
808+ // Clean up the signature
809+ signature = signature
810+ . replace ( / \s + / g, ' ' )
811+ . replace ( / : \s + / g, ': ' )
812+ . trim ( )
813+
814+ console . log ( 'Extracted raw signature:' , signature )
815+ return signature
816+ }
817+
795818/**
796819 * Process function declarations with full type information preservation
797820 */
@@ -800,43 +823,48 @@ export function processFunctionDeclaration(
800823 usedTypes : Set < string > ,
801824 isExported = true ,
802825) : string {
803- const signatureMatch = declaration . match ( / ^ .* ?(? = \{ | $ ) / )
804- if ( ! signatureMatch )
826+ console . log ( 'Processing declaration:' , declaration )
827+
828+ const signature = extractFunctionSignature ( declaration )
829+ if ( ! signature ) {
830+ console . log ( 'No valid signature found' )
805831 return declaration
832+ }
806833
807- const signature = signatureMatch [ 0 ] . trim ( )
834+ console . log ( 'Using signature:' , signature )
808835 const parseResult = parseFunctionDeclaration ( signature )
836+ console . log ( 'Parse result:' , parseResult )
809837
810- // Track used types, handling complex type expressions
838+ // Add types to usedTypes set
811839 const addTypeToUsed = ( type : string ) => {
812840 if ( ! type )
813841 return
814842
815- // Handle types with generics
816843 const typeMatches = type . match ( / ( [ A - Z _ ] \w * ) / gi) || [ ]
817844 typeMatches . forEach ( ( t ) => {
818845 if ( ! t . match ( / ^ ( v o i d | a n y | n u m b e r | s t r i n g | b o o l e a n | n u l l | u n d e f i n e d | n e v e r | u n k n o w n | P r o m i s e ) $ / ) ) {
819846 usedTypes . add ( t )
847+ console . log ( 'Added type to used:' , t )
820848 }
821849 } )
822850 }
823851
824- // Process return type and parameters
852+ // Process all types
825853 addTypeToUsed ( parseResult . returnType )
826854 addTypeToUsed ( parseResult . parameters )
827855
828- // Process generic type parameters
829856 if ( parseResult . genericParams ) {
830857 const genericContent = parseResult . genericParams . slice ( 1 , - 1 )
831858 genericContent . split ( ',' ) . forEach ( ( param ) => {
832859 const [ , constraint ] = param . split ( ' extends ' )
833860 if ( constraint ) {
834861 addTypeToUsed ( constraint )
862+ console . log ( 'Added generic constraint:' , constraint )
835863 }
836864 } )
837865 }
838866
839- // Preserve original parameter structure and return type
867+ // Construct the declaration, ensuring proper spacing and no duplicate colons
840868 return [
841869 isExported ? 'export ' : '' ,
842870 'declare ' ,
@@ -849,7 +877,7 @@ export function processFunctionDeclaration(
849877 '): ' ,
850878 parseResult . returnType ,
851879 ';' ,
852- ] . join ( '' ) . replace ( / \s + / g , ' ' ) . trim ( )
880+ ] . join ( '' )
853881}
854882
855883// Helper functions for line processing
0 commit comments