@@ -253,6 +253,31 @@ export class ImportManager {
253253 }
254254 }
255255
256+ /**
257+ * Helper method to remove trailing /index from import library names.
258+ * Creates new Import objects instead of mutating readonly properties.
259+ */
260+ private removeTrailingIndexFromImports ( imports : Import [ ] ) : Import [ ] {
261+ return imports . map ( imp => {
262+ if ( ! imp . libraryName . endsWith ( '/index' ) ) {
263+ return imp ;
264+ }
265+ const newLibraryName = imp . libraryName . replace ( / \/ i n d e x $ / , '' ) ;
266+
267+ // Create new import object instead of mutating readonly property
268+ if ( imp instanceof NamedImport ) {
269+ return new NamedImport ( newLibraryName , imp . specifiers , imp . defaultAlias ) ;
270+ } else if ( imp instanceof NamespaceImport ) {
271+ return new NamespaceImport ( newLibraryName , imp . alias ) ;
272+ } else if ( imp instanceof ExternalModuleImport ) {
273+ return new ExternalModuleImport ( newLibraryName , imp . alias ) ;
274+ } else if ( imp instanceof StringImport ) {
275+ return new StringImport ( newLibraryName ) ;
276+ }
277+ return imp ;
278+ } ) ;
279+ }
280+
256281 /**
257282 * Organize imports: remove unused, sort, and group.
258283 * Returns TextEdits to apply the changes.
@@ -351,9 +376,7 @@ export class ImportManager {
351376 // In modern mode, /index removal happens first so imports like './lib/index' and './lib' can merge
352377 // In legacy mode, we do it after merging to replicate the old extension's bug
353378 if ( this . config . removeTrailingIndex ( this . document . uri ) && ! this . config . legacyMode ( this . document . uri ) ) {
354- for ( const imp of keep . filter ( lib => lib . libraryName . endsWith ( '/index' ) ) ) {
355- imp . libraryName = imp . libraryName . replace ( / \/ i n d e x $ / , '' ) ;
356- }
379+ keep = this . removeTrailingIndexFromImports ( keep ) ;
357380 }
358381
359382 // Merge imports from same module (configurable)
@@ -448,9 +471,7 @@ export class ImportManager {
448471 // In legacy mode, we replicate the old extension's bug where /index removal happens after merging
449472 // This means './lib/index' and './lib' won't merge because they're different at merge time
450473 if ( this . config . removeTrailingIndex ( this . document . uri ) && this . config . legacyMode ( this . document . uri ) ) {
451- for ( const imp of keep . filter ( lib => lib . libraryName . endsWith ( '/index' ) ) ) {
452- imp . libraryName = imp . libraryName . replace ( / \/ i n d e x $ / , '' ) ;
453- }
474+ keep = this . removeTrailingIndexFromImports ( keep ) ;
454475 }
455476
456477 // Group imports
@@ -517,10 +538,12 @@ export class ImportManager {
517538 // Extract comments between imports (old TypeScript Hero moves them after imports)
518539 const commentsBetweenImports : string [ ] = [ ] ;
519540 for ( let i = importSectionStartLine ; i <= importSectionEndLine ; i ++ ) {
520- const lineText = this . document . lineAt ( i ) . text . trim ( ) ;
541+ const lineText = this . document . lineAt ( i ) . text ;
542+ const trimmedText = lineText . trim ( ) ;
521543 // Check if line is a comment (and not an import statement)
522- if ( ( lineText . startsWith ( '//' ) || lineText . startsWith ( '/*' ) || lineText . startsWith ( '*' ) ) &&
523- ! lineText . includes ( 'import ' ) ) {
544+ // Check the trimmed version but preserve the original with indentation
545+ if ( ( trimmedText . startsWith ( '//' ) || trimmedText . startsWith ( '/*' ) || trimmedText . startsWith ( '*' ) ) &&
546+ ! trimmedText . includes ( 'import ' ) ) {
524547 commentsBetweenImports . push ( lineText ) ;
525548 }
526549 }
0 commit comments