@@ -532,18 +532,87 @@ function createImportTrackingState(): ImportTrackingState {
532
532
}
533
533
534
534
function indentMultilineType ( type : string , baseIndent : string , isLast : boolean ) : string {
535
+ debugLog ( undefined , 'indent-multiline' , `Processing multiline type with baseIndent="${ baseIndent } ", isLast=${ isLast } ` )
536
+ debugLog ( undefined , 'indent-input' , `Input type:\n${ type } ` )
537
+
535
538
const lines = type . split ( '\n' )
536
- return lines
537
- . map ( ( line , i ) => {
538
- if ( i === 0 )
539
- return `${ baseIndent } ${ line } `
540
- const trimmed = line . trim ( )
541
- if ( ! trimmed )
542
- return ''
543
- return `${ baseIndent } ${ trimmed } `
544
- } )
545
- . filter ( Boolean )
546
- . join ( '\n' ) + ( isLast ? '' : ' |' )
539
+ debugLog ( undefined , 'indent-lines' , `Split into ${ lines . length } lines` )
540
+
541
+ if ( lines . length === 1 ) {
542
+ const result = `${ baseIndent } ${ type } ${ isLast ? '' : ' |' } `
543
+ debugLog ( undefined , 'indent-single' , `Single line result: ${ result } ` )
544
+ return result
545
+ }
546
+
547
+ // Initialize bracket stack with additional context
548
+ interface BracketInfo {
549
+ char : string
550
+ indent : string
551
+ isArray : boolean // Track if this is an Array type bracket
552
+ }
553
+ const bracketStack : BracketInfo [ ] = [ ]
554
+ debugLog ( undefined , 'indent-stack' , 'Initializing bracket stack' )
555
+
556
+ const formattedLines = lines . map ( ( line , i ) => {
557
+ const trimmed = line . trim ( )
558
+ if ( ! trimmed ) {
559
+ debugLog ( undefined , 'indent-empty' , `Empty line at index ${ i } ` )
560
+ return ''
561
+ }
562
+
563
+ // Track Array type specifically
564
+ const isArrayStart = trimmed . startsWith ( 'Array<' )
565
+ const openBrackets = ( trimmed . match ( / [ { < [ ] / g) || [ ] )
566
+ const closeBrackets = ( trimmed . match ( / [ } \] > ] / g) || [ ] )
567
+
568
+ debugLog ( undefined , 'indent-brackets' , `Line ${ i } : opens=${ openBrackets . length } , closes=${ closeBrackets . length } , isArray=${ isArrayStart } , content="${ trimmed } "` )
569
+
570
+ let currentIndent = baseIndent
571
+ if ( i > 0 || closeBrackets . length > 0 ) {
572
+ if ( closeBrackets . length > 0 && bracketStack . length > 0 ) {
573
+ const lastBracket = bracketStack [ bracketStack . length - 1 ]
574
+ // For Array closing bracket, use base indent
575
+ if ( lastBracket . isArray ) {
576
+ currentIndent = baseIndent
577
+ debugLog ( undefined , 'indent-close-array' , `Using base indent for Array closing: "${ currentIndent } "` )
578
+ }
579
+ else {
580
+ currentIndent = lastBracket . indent
581
+ debugLog ( undefined , 'indent-close' , `Using stack indent for closing: "${ currentIndent } "` )
582
+ }
583
+ bracketStack . pop ( )
584
+ }
585
+ else {
586
+ currentIndent = baseIndent + ' ' . repeat ( bracketStack . length )
587
+ debugLog ( undefined , 'indent-content' , `Using content indent at depth ${ bracketStack . length } : "${ currentIndent } "` )
588
+ }
589
+ }
590
+
591
+ // Handle opening brackets with Array context
592
+ if ( openBrackets . length > 0 ) {
593
+ openBrackets . forEach ( ( bracket ) => {
594
+ const isArrayBracket = trimmed . startsWith ( 'Array' ) && bracket === '<'
595
+ bracketStack . push ( {
596
+ char : bracket ,
597
+ indent : currentIndent ,
598
+ isArray : isArrayBracket ,
599
+ } )
600
+ debugLog ( undefined , 'indent-open' , `Pushed bracket "${ bracket } " with indent "${ currentIndent } ", isArray=${ isArrayBracket } ` )
601
+ } )
602
+ }
603
+
604
+ const formattedLine = `${ currentIndent } ${ trimmed } `
605
+ debugLog ( undefined , 'indent-line' , `Formatted line ${ i } : "${ formattedLine } "` )
606
+
607
+ if ( ! isLast && i === lines . length - 1 && ! formattedLine . endsWith ( ' |' ) ) {
608
+ return `${ formattedLine } |`
609
+ }
610
+ return formattedLine
611
+ } ) . filter ( Boolean )
612
+
613
+ const result = formattedLines . join ( '\n' )
614
+ debugLog ( undefined , 'indent-result' , `Final multiline result:\n${ result } ` )
615
+ return result
547
616
}
548
617
549
618
function inferValueType ( value : string ) : string {
@@ -576,83 +645,103 @@ function inferValueType(value: string): string {
576
645
* Infer array type from array literal with support for nested arrays and mixed elements
577
646
*/
578
647
function inferArrayType ( value : string , state ?: ProcessingState , indentLevel = 0 ) : string {
579
- debugLog ( state , 'infer-array' , `Inferring array type for: ${ value } ` )
648
+ debugLog ( state , 'infer-array-start' , `Starting array inference at level ${ indentLevel } ` )
649
+ debugLog ( state , 'infer-array-value' , `Input value:\n${ value } ` )
650
+
580
651
const content = value . slice ( 1 , - 1 ) . trim ( )
581
- if ( ! content )
652
+ if ( ! content ) {
653
+ debugLog ( state , 'infer-array-empty' , 'Empty array content' )
582
654
return 'unknown[]'
655
+ }
583
656
584
657
const baseIndent = ' ' . repeat ( indentLevel )
585
658
const elementIndent = ' ' . repeat ( indentLevel + 1 )
659
+ debugLog ( state , 'infer-array-indent' , `Base indent="${ baseIndent } ", Element indent="${ elementIndent } "` )
586
660
587
- // Handle const assertions first
588
661
const elements = splitArrayElements ( content , state )
662
+ debugLog ( state , 'array-split' , `Elements after split: ${ JSON . stringify ( elements ) } ` )
663
+
589
664
const allConstTuples = elements . every ( el => el . trim ( ) . endsWith ( 'as const' ) )
665
+ debugLog ( state , 'array-tuples' , `All const tuples: ${ allConstTuples } ` )
590
666
591
667
if ( allConstTuples ) {
592
668
const tuples = elements . map ( ( el ) => {
593
669
const tupleContent = el . slice ( 0 , el . indexOf ( 'as const' ) ) . trim ( )
594
670
return inferConstArrayType ( tupleContent , state )
595
671
} )
672
+ debugLog ( state , 'const-tuple' , `Tuples inferred: ${ tuples } ` )
596
673
return `Array<${ tuples . join ( ' | ' ) } >`
597
674
}
598
675
599
- // Process each element
600
- const elementTypes = elements . map ( ( element ) => {
676
+ const elementTypes = elements . map ( ( element , index ) => {
601
677
const trimmed = element . trim ( )
678
+ debugLog ( state , 'element-processing' , `Processing element ${ index } : "${ trimmed } "` )
602
679
603
- // Handle nested arrays
680
+ let type : string
604
681
if ( trimmed . startsWith ( '[' ) ) {
605
- return inferArrayType ( trimmed , state , indentLevel + 1 )
682
+ debugLog ( state , 'element-nested' , `Found nested array at index ${ index } ` )
683
+ type = inferArrayType ( trimmed , state , indentLevel + 1 )
606
684
}
607
-
608
- // Handle objects with proper indentation
609
- if ( trimmed . startsWith ( '{' ) ) {
610
- return inferComplexObjectType ( trimmed , state , indentLevel + 1 )
685
+ else if ( trimmed . startsWith ( '{' ) ) {
686
+ debugLog ( state , 'element-object' , `Found object at index ${ index } ` )
687
+ type = inferComplexObjectType ( trimmed , state , indentLevel + 1 )
611
688
}
612
-
613
- // Handle function expressions - always parenthesize
614
- if ( trimmed . includes ( '=>' ) || trimmed . includes ( 'function' ) ) {
689
+ else if ( trimmed . includes ( '=>' ) || trimmed . includes ( 'function' ) ) {
690
+ debugLog ( state , 'element-function' , `Found function at index ${ index } ` )
615
691
const funcType = extractFunctionType ( trimmed , state )
616
- return funcType ? `(${ funcType } )` : '((...args: any[]) => unknown)'
692
+ type = funcType ? `(${ funcType } )` : '((...args: any[]) => unknown)'
617
693
}
618
-
619
- // Handle method/function references
620
- if ( trimmed . includes ( '.' ) || / \w + \( / . test ( trimmed ) ) {
621
- return 'unknown'
694
+ else {
695
+ type = normalizeTypeReference ( trimmed )
622
696
}
623
697
624
- // Handle other literals
625
- return normalizeTypeReference ( trimmed )
698
+ debugLog ( state , 'element-type' , `Element ${ index } type: " ${ type } "` )
699
+ return type
626
700
} )
627
701
628
- // Format the array type with proper indentation
629
702
const types = elementTypes . filter ( Boolean )
630
- if ( types . length === 0 )
631
- return 'unknown[]'
703
+ debugLog ( state , 'types' , `Filtered types: ${ types . length } ` )
632
704
633
- // Check if we need multiline formatting
634
705
const needsMultiline = types . some ( type =>
635
- type . includes ( '\n' )
636
- || type . includes ( '{' )
637
- || type . length > 40
638
- || types . join ( ' | ' ) . length > 60 ,
706
+ type . includes ( '\n' ) || type . includes ( '{' ) || type . length > 40 || types . join ( ' | ' ) . length > 60 ,
639
707
)
708
+ debugLog ( state , 'multiline-check' , `Needs multiline: ${ needsMultiline } , Reason: ${
709
+ types . find ( type => type . includes ( '\n' ) )
710
+ ? 'contains newline'
711
+ : types . find ( type => type . includes ( '{' ) )
712
+ ? 'contains object'
713
+ : types . find ( type => type . length > 40 )
714
+ ? 'type too long'
715
+ : types . join ( ' | ' ) . length > 60 ? 'combined types too long' : 'none'
716
+ } `)
640
717
641
718
if ( needsMultiline ) {
719
+ debugLog ( state , 'multiline-start' , `Starting multiline formatting with ${ types . length } types` )
720
+
721
+ // Construct parts separately for better control
642
722
const formattedTypes = types . map ( ( type , index ) => {
643
723
const isLast = index === types . length - 1
644
- // For types that contain newlines
645
- if ( type . includes ( '\n' ) ) {
646
- return indentMultilineType ( type , elementIndent , isLast )
647
- }
648
- // For single-line types
649
- return `${ elementIndent } ${ type } ${ isLast ? '' : ' |' } `
724
+ debugLog ( state , 'type-formatting' , `Formatting type ${ index } , isLast: ${ isLast } ` )
725
+ const formatted = indentMultilineType ( type , elementIndent , isLast )
726
+ debugLog ( state , 'type-formatted' , `Type ${ index } formatted result:\n${ formatted } ` )
727
+ return formatted
650
728
} )
651
729
652
- return `Array<\n${ formattedTypes . join ( '\n' ) } \n${ baseIndent } >`
730
+ // Build multiline array with controlled indentation
731
+ const typeContent = formattedTypes . join ( '\n' )
732
+ const result = [
733
+ `${ baseIndent } Array<` ,
734
+ typeContent ,
735
+ `${ baseIndent } >` ,
736
+ ] . join ( '\n' )
737
+
738
+ debugLog ( state , 'multiline-result' , `Final multiline result:\n${ result } ` )
739
+ return result
653
740
}
654
741
655
- return `Array<${ types . join ( ' | ' ) } >`
742
+ const singleLineResult = `Array<${ types . join ( ' | ' ) } >`
743
+ debugLog ( state , 'single-line-array' , `Single-line array type: ${ singleLineResult } ` )
744
+ return singleLineResult
656
745
}
657
746
658
747
/**
0 commit comments