/** * @angular-modernizer/plugin-angular - Import Cleanup Helper * * Helper for managing imports in focused services after Service Bag transformation. * Works WITH ImportManager, SymbolLocator, and DependencyAnalyzer from API. * * Philosophy: "Smart Import Management" * - Analyzes what types/dependencies are actually used in code * - Adds required imports for dependencies and types * - Removes unused imports from original service * - Resolves correct import paths via SymbolLocator * * Use Case: Service Bag Transform * - Add imports to focused services (dependencies + types) * - Remove unused imports from original service after splitting * - Preserve imports still used in original service */ import type { ClassDeclaration, SourceFile } from 'ts-morph'; import type { ImportManager, SymbolLocator } from '@angular-modernizer/api'; import type { ConstructorDependency } from './constructor-dependency-helper.js'; /** * Represents information about imports to add to a file. */ export interface ImportsToAdd { /** * Named imports to add (e.g., 'HttpClient', 'Observable'). * Supports aliases: { name: 'Model', alias: 'DomainModel', moduleSpecifier: './model' } */ namedImports: { name: string; moduleSpecifier: string; alias?: string; kind?: 'named' | 'namespace' | 'default'; }[]; /** * Type imports to add (e.g., 'User', 'Order'). * Supports aliases: { name: 'User', alias: 'UserModel', moduleSpecifier: './user' } */ typeImports: { name: string; moduleSpecifier: string; alias?: string; kind?: 'named' | 'namespace' | 'default'; }[]; } /** * Represents information about imports to remove from a file. */ export interface ImportsToRemove { /** * Import names to remove (e.g., 'HttpClient', 'Observable'). */ importNames: string[]; } /** * Import Cleanup Helper - manages imports in focused and original services. * * This helper works WITH the existing ImportManager and SymbolLocator from @angular-modernizer/api. * It focuses on analyzing what imports are needed and orchestrating the add/remove operations. * * @example * ```typescript * const helper = new ImportCleanupHelper(importManager, symbolLocator); * * // Add imports to focused service * const importsToAdd = helper.analyzeRequiredImports( * focusedServiceClass, * dependencies, * originalServicePath * ); * helper.addImports(focusedServiceFile, importsToAdd); * * // Remove unused imports from original service * const importsToRemove = helper.analyzeUnusedImports( * originalServiceClass, * ['HttpClient', 'Observable'] * ); * helper.removeImports(originalServiceFile, importsToRemove); * ``` */ export declare class ImportCleanupHelper { private readonly importManager; private readonly symbolLocator; private readonly methodBodyAnalyzer; constructor(importManager: ImportManager, symbolLocator: SymbolLocator); /** * Analyzes what imports are required for a focused service. * * Determines: * 1. Dependency imports (HttpClient, LoggerService, etc.) * 2. Type imports used in method signatures (User, Order, etc.) * 3. Correct module specifiers via SymbolLocator * * @param classDecl - Focused service class declaration * @param dependencies - Constructor dependencies used by this service * @param originalServiceFile - Original service source file (for relative imports) * @returns Object with named imports and type imports to add * * @example * ```typescript * const importsToAdd = helper.analyzeRequiredImports( * dataRetrievalServiceClass, * [{ name: 'http', type: 'HttpClient', ... }], * originalSourceFile * ); * // Result: { * // namedImports: [{ name: 'HttpClient', moduleSpecifier: '@angular/common/http' }], * // typeImports: [{ name: 'User', moduleSpecifier: './user.model' }] * // } * ``` */ analyzeRequiredImports(classDecl: ClassDeclaration, dependencies: ConstructorDependency[], originalServiceFile: SourceFile): ImportsToAdd; /** * Analyzes what imports are no longer used in the original service. * * After splitting, some imports may no longer be needed in the original service. * This method identifies which imports can be safely removed by checking ALL imports * in the source file, not just moved dependencies. * * @param classDecl - Original service class declaration * @param movedDependencies - Dependency types that were moved to focused services (for reference) * @returns Object with import names to remove * * @example * ```typescript * const importsToRemove = helper.analyzeUnusedImports( * originalServiceClass, * ['HttpClient'] // Moved constructor dependencies * ); * // Result: { importNames: ['HttpClient', 'Observable', 'map'] } // All unused imports * ``` */ analyzeUnusedImports(classDecl: ClassDeclaration, _movedDependencies: string[]): ImportsToRemove; /** * Adds imports to a source file using ImportManager. * * Adds both named imports (classes, functions) and type imports (interfaces, types). * Uses ImportManager to handle the actual AST manipulation. * Supports aliased imports: `import { Model as DomainModel } from './model'` * * @param sourceFile - Source file to add imports to * @param imports - Imports to add * * @example * ```typescript * helper.addImports(focusedServiceFile, { * namedImports: [ * { name: 'HttpClient', moduleSpecifier: '@angular/common/http' }, * { name: 'Injectable', moduleSpecifier: '@angular/core' }, * { name: 'Model', alias: 'DomainModel', moduleSpecifier: './model' } * ], * typeImports: [ * { name: 'User', moduleSpecifier: './user.model' } * ] * }); * ``` */ addImports(sourceFile: SourceFile, imports: ImportsToAdd): void; /** * Removes imports from a source file using ImportManager. * * Removes imports that are no longer used in the file. * Uses ImportManager to handle the actual AST manipulation. * * @param sourceFile - Source file to remove imports from * @param imports - Imports to remove * * @example * ```typescript * helper.removeImports(originalServiceFile, { * importNames: ['HttpClient', 'Observable'] * }); * ``` */ removeImports(sourceFile: SourceFile, imports: ImportsToRemove): void; /** * Extracts type references from method signatures in a class. * * Finds types used in: * - Return types: `getData(): Observable` * - Parameter types: `processUser(user: User)` * - Generic types: `Observable`, `Array` * * @param classDecl - Class declaration to analyze * @returns Array of type names * @private */ private extractTypeReferences; /** * Extracts type names from a type node text. * * Handles: * - Simple types: `User` → ['User'] * - Generic types: `Observable` → ['Observable', 'User'] * - Union types: `User | Admin` → ['User', 'Admin'] * - Array types: `User[]` → ['User'] * * @param typeText - Type node text * @param typeReferences - Set to add type references to * @private */ private extractTypesFromTypeNode; /** * Finds alias information for a type name in the original service file. * * Checks if the given type name is imported with an alias in the original service. * For example, if the original service has `import { Model as DomainModel }`, * calling this with 'DomainModel' returns { originalName: 'Model', alias: 'DomainModel' }. * * @param typeName - Type name to check (could be original name or alias) * @param originalServiceFile - Original service source file * @returns Alias info if found, undefined otherwise * @private */ private findAliasInfo; /** * Extracts identifiers used in method bodies and maps them to their module specifiers. * * Scans all method bodies for identifiers (function calls, property accesses) and * maps them back to their import declarations in the original service file. * * Handles: * - Named imports: `import { map, filter } from 'rxjs/operators'` * - Namespace imports: `import * as _ from 'lodash'` * - Default imports: `import moment from 'moment'` * - Aliased imports: `import { Model as DomainModel } from './model'` * * Examples: * - RxJS operators: `.pipe(map(...))` → `{ name: 'map', moduleSpecifier: 'rxjs/operators' }` * - Utility functions: `parseData(...)` → `{ name: 'parseData', moduleSpecifier: './utils' }` * - Aliased imports: `new DomainModel()` → `{ name: 'Model', alias: 'DomainModel', moduleSpecifier: './model' }` * * @param classDecl - Class declaration to analyze * @param originalServiceFile - Original service source file to resolve imports from * @returns Array of identifiers with their module specifiers and optional aliases * @private */ private extractMethodBodyIdentifiers; /** * Resolves module specifier for a type using SymbolLocator. * * Determines correct import path (relative or absolute). * Falls back to original file's imports if not found in symbol map. * * @param typeName - Type name to resolve (e.g., 'HttpClient', 'User') * @param originalServiceFile - Original service source file * @param focusedServiceFile - Focused service source file to check for existing imports * @returns Module specifier or undefined if not found * @private */ private resolveModuleSpecifier; } //# sourceMappingURL=import-cleanup-helper.d.ts.map