@angular-modernizer/api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +507 -0
  3. package/dist/analysis/complexity-metrics-calculator.d.ts +99 -0
  4. package/dist/analysis/complexity-metrics-calculator.d.ts.map +1 -0
  5. package/dist/analysis/complexity-metrics-calculator.js +195 -0
  6. package/dist/analysis/complexity-metrics-calculator.js.map +1 -0
  7. package/dist/analysis/dependency-analyzer.d.ts +227 -0
  8. package/dist/analysis/dependency-analyzer.d.ts.map +1 -0
  9. package/dist/analysis/dependency-analyzer.js +451 -0
  10. package/dist/analysis/dependency-analyzer.js.map +1 -0
  11. package/dist/analysis/external-template-loader.d.ts +44 -0
  12. package/dist/analysis/external-template-loader.d.ts.map +1 -0
  13. package/dist/analysis/external-template-loader.js +69 -0
  14. package/dist/analysis/external-template-loader.js.map +1 -0
  15. package/dist/analysis/selector-mapper.d.ts +77 -0
  16. package/dist/analysis/selector-mapper.d.ts.map +1 -0
  17. package/dist/analysis/selector-mapper.js +146 -0
  18. package/dist/analysis/selector-mapper.js.map +1 -0
  19. package/dist/analysis/service-detector.d.ts +164 -0
  20. package/dist/analysis/service-detector.d.ts.map +1 -0
  21. package/dist/analysis/service-detector.js +231 -0
  22. package/dist/analysis/service-detector.js.map +1 -0
  23. package/dist/analysis/service-pattern-recognizer.d.ts +247 -0
  24. package/dist/analysis/service-pattern-recognizer.d.ts.map +1 -0
  25. package/dist/analysis/service-pattern-recognizer.js +444 -0
  26. package/dist/analysis/service-pattern-recognizer.js.map +1 -0
  27. package/dist/analysis/symbol-locator.d.ts +81 -0
  28. package/dist/analysis/symbol-locator.d.ts.map +1 -0
  29. package/dist/analysis/symbol-locator.js +128 -0
  30. package/dist/analysis/symbol-locator.js.map +1 -0
  31. package/dist/analysis/template-analyzer-usage.d.ts +144 -0
  32. package/dist/analysis/template-analyzer-usage.d.ts.map +1 -0
  33. package/dist/analysis/template-analyzer-usage.js +474 -0
  34. package/dist/analysis/template-analyzer-usage.js.map +1 -0
  35. package/dist/analysis/template-analyzer.d.ts +80 -0
  36. package/dist/analysis/template-analyzer.d.ts.map +1 -0
  37. package/dist/analysis/template-analyzer.js +146 -0
  38. package/dist/analysis/template-analyzer.js.map +1 -0
  39. package/dist/index.d.ts +23 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +22 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/investigation/angular-symbol-finder.d.ts +76 -0
  44. package/dist/investigation/angular-symbol-finder.d.ts.map +1 -0
  45. package/dist/investigation/angular-symbol-finder.js +199 -0
  46. package/dist/investigation/angular-symbol-finder.js.map +1 -0
  47. package/dist/investigation/call-graph-builder.d.ts +85 -0
  48. package/dist/investigation/call-graph-builder.d.ts.map +1 -0
  49. package/dist/investigation/call-graph-builder.js +196 -0
  50. package/dist/investigation/call-graph-builder.js.map +1 -0
  51. package/dist/investigation/codebase-searcher.d.ts +99 -0
  52. package/dist/investigation/codebase-searcher.d.ts.map +1 -0
  53. package/dist/investigation/codebase-searcher.js +201 -0
  54. package/dist/investigation/codebase-searcher.js.map +1 -0
  55. package/dist/investigation/stack-trace-parser.d.ts +70 -0
  56. package/dist/investigation/stack-trace-parser.d.ts.map +1 -0
  57. package/dist/investigation/stack-trace-parser.js +117 -0
  58. package/dist/investigation/stack-trace-parser.js.map +1 -0
  59. package/dist/investigation/type-resolver.d.ts +59 -0
  60. package/dist/investigation/type-resolver.d.ts.map +1 -0
  61. package/dist/investigation/type-resolver.js +111 -0
  62. package/dist/investigation/type-resolver.js.map +1 -0
  63. package/dist/investigation/usage-finder.d.ts +69 -0
  64. package/dist/investigation/usage-finder.d.ts.map +1 -0
  65. package/dist/investigation/usage-finder.js +132 -0
  66. package/dist/investigation/usage-finder.js.map +1 -0
  67. package/dist/metrics/complexity-metrics.d.ts +196 -0
  68. package/dist/metrics/complexity-metrics.d.ts.map +1 -0
  69. package/dist/metrics/complexity-metrics.js +445 -0
  70. package/dist/metrics/complexity-metrics.js.map +1 -0
  71. package/dist/public-api.d.ts +77 -0
  72. package/dist/public-api.d.ts.map +1 -0
  73. package/dist/public-api.js +50 -0
  74. package/dist/public-api.js.map +1 -0
  75. package/dist/transformation/import-manager.d.ts +276 -0
  76. package/dist/transformation/import-manager.d.ts.map +1 -0
  77. package/dist/transformation/import-manager.js +488 -0
  78. package/dist/transformation/import-manager.js.map +1 -0
  79. package/dist/transformation/ng-morph-adapter.d.ts +111 -0
  80. package/dist/transformation/ng-morph-adapter.d.ts.map +1 -0
  81. package/dist/transformation/ng-morph-adapter.js +179 -0
  82. package/dist/transformation/ng-morph-adapter.js.map +1 -0
  83. package/dist/transformation/ngmodule-manager.d.ts +145 -0
  84. package/dist/transformation/ngmodule-manager.d.ts.map +1 -0
  85. package/dist/transformation/ngmodule-manager.js +356 -0
  86. package/dist/transformation/ngmodule-manager.js.map +1 -0
  87. package/package.json +62 -0
  88. package/src/analysis/complexity-metrics-calculator.ts +253 -0
  89. package/src/analysis/dependency-analyzer.ts +720 -0
  90. package/src/analysis/external-template-loader.ts +79 -0
  91. package/src/analysis/selector-mapper.ts +186 -0
  92. package/src/analysis/service-detector.ts +280 -0
  93. package/src/analysis/service-pattern-recognizer.ts +545 -0
  94. package/src/analysis/symbol-locator.ts +170 -0
  95. package/src/analysis/template-analyzer-usage.ts +614 -0
  96. package/src/analysis/template-analyzer.ts +208 -0
  97. package/src/index.ts +51 -0
  98. package/src/investigation/angular-symbol-finder.ts +263 -0
  99. package/src/investigation/call-graph-builder.ts +298 -0
  100. package/src/investigation/codebase-searcher.ts +286 -0
  101. package/src/investigation/stack-trace-parser.ts +166 -0
  102. package/src/investigation/type-resolver.ts +144 -0
  103. package/src/investigation/usage-finder.ts +198 -0
  104. package/src/metrics/complexity-metrics.ts +617 -0
  105. package/src/public-api.ts +119 -0
  106. package/src/transformation/import-manager.ts +626 -0
  107. package/src/transformation/ng-morph-adapter.ts +252 -0
  108. package/src/transformation/ngmodule-manager.ts +450 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector-mapper.d.ts","sourceRoot":"","sources":["../../src/analysis/selector-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAGV,OAAO,EAER,MAAM,UAAU,CAAC;AAGlB;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAkC;IAErD;;;;;;;;OAQG;IACH,uBAAuB,CACrB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS;IAQrB;;;;;;;OAOG;IACH,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAKrD;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IA6BpC;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;CAetB"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @angular-modernizer/api - Selector Mapper
3
+ *
4
+ * Reusable selector-to-className mapping utility.
5
+ * Extracted from Phase 3's selector map caching for reuse across components.
6
+ *
7
+ * Philosophy: "Build Once, Use Everywhere"
8
+ * - O(n) initial build, O(1) lookups
9
+ * - Lazy initialization (only builds when first needed)
10
+ * - Universal coverage (standard `` + custom decorators)
11
+ */
12
+ import { SyntaxKind } from 'ts-morph';
13
+ /**
14
+ * Selector Mapper - Maps component selectors to class names.
15
+ *
16
+ * Provides O(1) selector lookups using a cached map built from project files.
17
+ * Supports both standard `` decorators and custom decorators (e.g., ``).
18
+ */
19
+ export class SelectorMapper {
20
+ selectorMap;
21
+ /**
22
+ * Find a component class name by its selector.
23
+ *
24
+ * Builds the selector map lazily on first call, then reuses for O(1) lookups.
25
+ *
26
+ * @param project - ts-morph Project
27
+ * @param selector - Component selector (e.g., 'app-user-profile')
28
+ * @returns Class name (e.g., 'UserProfileComponent') or undefined if not found
29
+ */
30
+ findComponentBySelector(project, selector) {
31
+ // Build selector map lazily on first use
32
+ this.selectorMap ??= this.buildSelectorMap(project);
33
+ // O(1) lookup in cached map
34
+ return this.selectorMap.get(selector);
35
+ }
36
+ /**
37
+ * Get the complete selector map.
38
+ *
39
+ * Builds the map lazily if not yet built.
40
+ *
41
+ * @param project - ts-morph Project
42
+ * @returns Map of selector → className
43
+ */
44
+ getSelectorMap(project) {
45
+ this.selectorMap ??= this.buildSelectorMap(project);
46
+ return this.selectorMap;
47
+ }
48
+ /**
49
+ * Clear the cached selector map.
50
+ *
51
+ * Useful for testing or when project files have changed significantly.
52
+ */
53
+ clearCache() {
54
+ this.selectorMap = undefined;
55
+ }
56
+ /**
57
+ * Build a comprehensive selector map for the entire project.
58
+ *
59
+ * Scans all source files once to build selector → className mapping.
60
+ * Performance: O(n) initial build, O(1) lookup per selector.
61
+ *
62
+ * @param project - ts-morph Project
63
+ * @returns Map of selector → className
64
+ * @private
65
+ */
66
+ buildSelectorMap(project) {
67
+ const selectorMap = new Map();
68
+ const sourceFiles = project.getSourceFiles();
69
+ for (const sourceFile of sourceFiles) {
70
+ // Skip node_modules and test files for performance
71
+ const filePath = sourceFile.getFilePath();
72
+ if (filePath.includes('node_modules') ||
73
+ filePath.includes('.spec.ts') ||
74
+ filePath.includes('.d.ts')) {
75
+ continue;
76
+ }
77
+ const classes = sourceFile.getClasses();
78
+ for (const classDecl of classes) {
79
+ const className = classDecl.getName();
80
+ if (!className) {
81
+ continue;
82
+ }
83
+ // Check if this class has a @Component decorator
84
+ // (regardless of other decorators like @ExportComponent)
85
+ const componentDecorator = this.findDecorator(classDecl, 'Component');
86
+ if (componentDecorator) {
87
+ // Extract selector from @Component metadata
88
+ const selector = this.extractSelectorFromDecorator(componentDecorator);
89
+ if (selector) {
90
+ // Add to map: selector → className
91
+ selectorMap.set(selector, className);
92
+ }
93
+ }
94
+ }
95
+ }
96
+ return selectorMap;
97
+ }
98
+ /**
99
+ * Extract the selector from a `` decorator.
100
+ *
101
+ * @param decorator - The `` decorator
102
+ * @returns The selector string or undefined
103
+ * @private
104
+ */
105
+ extractSelectorFromDecorator(decorator) {
106
+ const args = decorator.getArguments();
107
+ if (args.length === 0) {
108
+ return undefined;
109
+ }
110
+ const metadataObj = args[0];
111
+ if (!metadataObj ||
112
+ metadataObj.getKind() !== SyntaxKind.ObjectLiteralExpression) {
113
+ return undefined;
114
+ }
115
+ const objLiteral = metadataObj;
116
+ const selectorProperty = objLiteral.getProperty('selector');
117
+ if (selectorProperty) {
118
+ const initializer = selectorProperty.getChildAtIndex(2); // Skip name and colon
119
+ const text = initializer.getText();
120
+ // Remove quotes if present
121
+ return text.replaceAll(/^['"`]|['"`]$/g, '');
122
+ }
123
+ return undefined;
124
+ }
125
+ /**
126
+ * Find a decorator by name on a class declaration.
127
+ *
128
+ * Supports both standard decorators (``) and custom decorators (``).
129
+ *
130
+ * @param classDecl - Class declaration
131
+ * @param decoratorName - Decorator name (without @)
132
+ * @returns Decorator or undefined
133
+ * @private
134
+ */
135
+ findDecorator(classDecl, decoratorName) {
136
+ const decorators = classDecl.getDecorators();
137
+ for (const decorator of decorators) {
138
+ const name = decorator.getName();
139
+ if (name === decoratorName) {
140
+ return decorator;
141
+ }
142
+ }
143
+ return undefined;
144
+ }
145
+ }
146
+ //# sourceMappingURL=selector-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector-mapper.js","sourceRoot":"","sources":["../../src/analysis/selector-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACjB,WAAW,CAAkC;IAErD;;;;;;;;OAQG;IACH,uBAAuB,CACrB,OAAgB,EAChB,QAAgB;QAEhB,yCAAyC;QACzC,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,4BAA4B;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,OAAgB;QAC7B,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED;;;;;;;;;OASG;IACK,gBAAgB,CAAC,OAAgB;QACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QAE7C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,mDAAmD;YACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;YAC1C,IACE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC;gBACjC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAC7B,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAC1B,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,CAAC;YAExC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;gBAChC,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;gBACtC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,SAAS;gBACX,CAAC;gBAED,iDAAiD;gBACjD,yDAAyD;gBACzD,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAEtE,IAAI,kBAAkB,EAAE,CAAC;oBACvB,4CAA4C;oBAC5C,MAAM,QAAQ,GACZ,IAAI,CAAC,4BAA4B,CAAC,kBAAkB,CAAC,CAAC;oBAExD,IAAI,QAAQ,EAAE,CAAC;wBACb,mCAAmC;wBACnC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACK,4BAA4B,CAClC,SAAoB;QAEpB,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IACE,CAAC,WAAW;YACZ,WAAW,CAAC,OAAO,EAAE,KAAK,UAAU,CAAC,uBAAuB,EAC5D,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,UAAU,GAAG,WAAsC,CAAC;QAC1D,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAE5D,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,WAAW,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;YAC/E,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;YACnC,2BAA2B;YAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;;;;OASG;IACK,aAAa,CACnB,SAA2B,EAC3B,aAAqB;QAErB,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC;QAE7C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC3B,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @angular-modernizer/api - Service Detector
3
+ *
4
+ * Centralized service detection API with caching and bulk operations.
5
+ * Single source of truth for service detection across all analysis rules.
6
+ *
7
+ * ARCHITECTURE:
8
+ * - Wraps ServicePatternRecognizer for consistent detection
9
+ * - Provides caching to avoid redundant AST traversal
10
+ * - Supports bulk detection for performance
11
+ * - Used by all analysis rules that need service detection
12
+ */
13
+ import type { SourceFile, ClassDeclaration } from 'ts-morph';
14
+ import type { ServicePatternRecognizer, ServiceDetectionResult } from './service-pattern-recognizer.js';
15
+ /**
16
+ * Bulk detection result for multiple classes.
17
+ */
18
+ export interface BulkDetectionResult {
19
+ /** Map of class name to detection result */
20
+ results: Map<string, ServiceDetectionResult>;
21
+ /** Total number of services detected */
22
+ serviceCount: number;
23
+ /** Total number of classes analyzed */
24
+ totalCount: number;
25
+ /** Detection time in milliseconds */
26
+ detectionTimeMs: number;
27
+ }
28
+ /**
29
+ * ServiceDetector - Centralized service detection with caching.
30
+ *
31
+ * SINGLE SOURCE OF TRUTH:
32
+ * - All analysis rules should use this detector
33
+ * - Ensures consistent service detection across rules
34
+ * - Provides performance optimization through caching
35
+ *
36
+ * USAGE:
37
+ * ```typescript
38
+ * const detector = new ServiceDetector(recognizer);
39
+ *
40
+ * // Single detection
41
+ * const result = detector.detectService(classDecl);
42
+ *
43
+ * // Bulk detection
44
+ * const bulk = detector.detectServicesInFile(sourceFile);
45
+ *
46
+ * // Cache management
47
+ * detector.clearCache();
48
+ * ```
49
+ */
50
+ export declare class ServiceDetector {
51
+ private readonly recognizer;
52
+ private readonly cache;
53
+ /**
54
+ * Create a new ServiceDetector.
55
+ *
56
+ * @param recognizer - ServicePatternRecognizer instance
57
+ */
58
+ constructor(recognizer: ServicePatternRecognizer);
59
+ /**
60
+ * Detect if a class is a service with caching.
61
+ *
62
+ * Results are cached by file path + class name for performance.
63
+ *
64
+ * @param classDecl - The class declaration to analyze
65
+ * @returns Service detection result with confidence
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const result = detector.detectService(classDecl);
70
+ * if (result.isService && result.confidence >= 0.7) {
71
+ * console.info(`High confidence service detected via ${result.detectionMethod}`);
72
+ * }
73
+ * ```
74
+ */
75
+ detectService(classDecl: ClassDeclaration): ServiceDetectionResult;
76
+ /**
77
+ * Simple check if a class is a service (cached).
78
+ *
79
+ * @param classDecl - The class declaration to check
80
+ * @returns True if detected as service
81
+ */
82
+ isService(classDecl: ClassDeclaration): boolean;
83
+ /**
84
+ * Detect all services in a source file (bulk operation).
85
+ *
86
+ * More efficient than detecting each class individually.
87
+ *
88
+ * @param sourceFile - The source file to analyze
89
+ * @returns Bulk detection result with statistics
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const bulk = detector.detectServicesInFile(sourceFile);
94
+ * console.info(`Found ${bulk.serviceCount} services in ${bulk.detectionTimeMs}ms`);
95
+ *
96
+ * for (const [className, result] of bulk.results) {
97
+ * if (result.isService) {
98
+ * console.info(`${className}: ${result.detectionMethod} (${result.confidence})`);
99
+ * }
100
+ * }
101
+ * ```
102
+ */
103
+ detectServicesInFile(sourceFile: SourceFile): BulkDetectionResult;
104
+ /**
105
+ * Detect services in multiple source files (bulk operation).
106
+ *
107
+ * @param sourceFiles - Array of source files to analyze
108
+ * @returns Bulk detection result with combined statistics
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const files = project.getSourceFiles();
113
+ * const bulk = detector.detectServicesInFiles(files);
114
+ * console.info(`Found ${bulk.serviceCount} services across ${files.length} files`);
115
+ * ```
116
+ */
117
+ detectServicesInFiles(sourceFiles: SourceFile[]): BulkDetectionResult;
118
+ /**
119
+ * Filter classes to only services.
120
+ *
121
+ * @param classes - Array of class declarations
122
+ * @returns Array of service class declarations
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const allClasses = sourceFile.getClasses();
127
+ * const services = detector.filterServices(allClasses);
128
+ * console.info(`Found ${services.length} services out of ${allClasses.length} classes`);
129
+ * ```
130
+ */
131
+ filterServices(classes: ClassDeclaration[]): ClassDeclaration[];
132
+ /**
133
+ * Get detection statistics from cache.
134
+ *
135
+ * @returns Statistics about cached detections
136
+ */
137
+ getCacheStatistics(): {
138
+ totalEntries: number;
139
+ serviceEntries: number;
140
+ nonServiceEntries: number;
141
+ };
142
+ /**
143
+ * Clear the detection cache.
144
+ *
145
+ * Call this when the AST has been modified and cached results
146
+ * may be stale.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * // After modifying files
151
+ * await project.save();
152
+ * detector.clearCache();
153
+ * ```
154
+ */
155
+ clearCache(): void;
156
+ /**
157
+ * Get cache key for a class declaration.
158
+ *
159
+ * @param classDecl - The class declaration
160
+ * @returns Cache key string
161
+ */
162
+ private getCacheKey;
163
+ }
164
+ //# sourceMappingURL=service-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-detector.d.ts","sourceRoot":"","sources":["../../src/analysis/service-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAExG;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAE7C,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IAErB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2B;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAE5D;;;;OAIG;gBACS,UAAU,EAAE,wBAAwB;IAKhD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,SAAS,EAAE,gBAAgB,GAAG,sBAAsB;IAgBlE;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO;IAI/C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,mBAAmB;IA+BjE;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,mBAAmB;IA+BrE;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE;IAI/D;;;;OAIG;IACH,kBAAkB,IAAI;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;KAC3B;IAmBD;;;;;;;;;;;;OAYG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CAKpB"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * @angular-modernizer/api - Service Detector
3
+ *
4
+ * Centralized service detection API with caching and bulk operations.
5
+ * Single source of truth for service detection across all analysis rules.
6
+ *
7
+ * ARCHITECTURE:
8
+ * - Wraps ServicePatternRecognizer for consistent detection
9
+ * - Provides caching to avoid redundant AST traversal
10
+ * - Supports bulk detection for performance
11
+ * - Used by all analysis rules that need service detection
12
+ */
13
+ /**
14
+ * ServiceDetector - Centralized service detection with caching.
15
+ *
16
+ * SINGLE SOURCE OF TRUTH:
17
+ * - All analysis rules should use this detector
18
+ * - Ensures consistent service detection across rules
19
+ * - Provides performance optimization through caching
20
+ *
21
+ * USAGE:
22
+ * ```typescript
23
+ * const detector = new ServiceDetector(recognizer);
24
+ *
25
+ * // Single detection
26
+ * const result = detector.detectService(classDecl);
27
+ *
28
+ * // Bulk detection
29
+ * const bulk = detector.detectServicesInFile(sourceFile);
30
+ *
31
+ * // Cache management
32
+ * detector.clearCache();
33
+ * ```
34
+ */
35
+ export class ServiceDetector {
36
+ recognizer;
37
+ cache;
38
+ /**
39
+ * Create a new ServiceDetector.
40
+ *
41
+ * @param recognizer - ServicePatternRecognizer instance
42
+ */
43
+ constructor(recognizer) {
44
+ this.recognizer = recognizer;
45
+ this.cache = new Map();
46
+ }
47
+ /**
48
+ * Detect if a class is a service with caching.
49
+ *
50
+ * Results are cached by file path + class name for performance.
51
+ *
52
+ * @param classDecl - The class declaration to analyze
53
+ * @returns Service detection result with confidence
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const result = detector.detectService(classDecl);
58
+ * if (result.isService && result.confidence >= 0.7) {
59
+ * console.info(`High confidence service detected via ${result.detectionMethod}`);
60
+ * }
61
+ * ```
62
+ */
63
+ detectService(classDecl) {
64
+ const cacheKey = this.getCacheKey(classDecl);
65
+ // Check cache first
66
+ const cached = this.cache.get(cacheKey);
67
+ if (cached) {
68
+ return cached;
69
+ }
70
+ // Detect and cache result
71
+ const result = this.recognizer.detectService(classDecl);
72
+ this.cache.set(cacheKey, result);
73
+ return result;
74
+ }
75
+ /**
76
+ * Simple check if a class is a service (cached).
77
+ *
78
+ * @param classDecl - The class declaration to check
79
+ * @returns True if detected as service
80
+ */
81
+ isService(classDecl) {
82
+ return this.detectService(classDecl).isService;
83
+ }
84
+ /**
85
+ * Detect all services in a source file (bulk operation).
86
+ *
87
+ * More efficient than detecting each class individually.
88
+ *
89
+ * @param sourceFile - The source file to analyze
90
+ * @returns Bulk detection result with statistics
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const bulk = detector.detectServicesInFile(sourceFile);
95
+ * console.info(`Found ${bulk.serviceCount} services in ${bulk.detectionTimeMs}ms`);
96
+ *
97
+ * for (const [className, result] of bulk.results) {
98
+ * if (result.isService) {
99
+ * console.info(`${className}: ${result.detectionMethod} (${result.confidence})`);
100
+ * }
101
+ * }
102
+ * ```
103
+ */
104
+ detectServicesInFile(sourceFile) {
105
+ const startTime = Date.now();
106
+ const results = new Map();
107
+ const classes = sourceFile.getClasses();
108
+ let serviceCount = 0;
109
+ for (const classDecl of classes) {
110
+ const className = classDecl.getName();
111
+ if (!className) {
112
+ continue;
113
+ }
114
+ const result = this.detectService(classDecl);
115
+ results.set(className, result);
116
+ if (result.isService) {
117
+ serviceCount++;
118
+ }
119
+ }
120
+ const endTime = Date.now();
121
+ return {
122
+ results,
123
+ serviceCount,
124
+ totalCount: classes.length,
125
+ detectionTimeMs: endTime - startTime,
126
+ };
127
+ }
128
+ /**
129
+ * Detect services in multiple source files (bulk operation).
130
+ *
131
+ * @param sourceFiles - Array of source files to analyze
132
+ * @returns Bulk detection result with combined statistics
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const files = project.getSourceFiles();
137
+ * const bulk = detector.detectServicesInFiles(files);
138
+ * console.info(`Found ${bulk.serviceCount} services across ${files.length} files`);
139
+ * ```
140
+ */
141
+ detectServicesInFiles(sourceFiles) {
142
+ const startTime = Date.now();
143
+ const results = new Map();
144
+ let serviceCount = 0;
145
+ let totalCount = 0;
146
+ for (const sourceFile of sourceFiles) {
147
+ const fileResult = this.detectServicesInFile(sourceFile);
148
+ // Merge results with class name prefixed by file path for uniqueness
149
+ const filePath = sourceFile.getFilePath();
150
+ for (const [className, result] of fileResult.results) {
151
+ const key = `${filePath}:${className}`;
152
+ results.set(key, result);
153
+ }
154
+ serviceCount += fileResult.serviceCount;
155
+ totalCount += fileResult.totalCount;
156
+ }
157
+ const endTime = Date.now();
158
+ return {
159
+ results,
160
+ serviceCount,
161
+ totalCount,
162
+ detectionTimeMs: endTime - startTime,
163
+ };
164
+ }
165
+ /**
166
+ * Filter classes to only services.
167
+ *
168
+ * @param classes - Array of class declarations
169
+ * @returns Array of service class declarations
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const allClasses = sourceFile.getClasses();
174
+ * const services = detector.filterServices(allClasses);
175
+ * console.info(`Found ${services.length} services out of ${allClasses.length} classes`);
176
+ * ```
177
+ */
178
+ filterServices(classes) {
179
+ return classes.filter((cls) => this.isService(cls));
180
+ }
181
+ /**
182
+ * Get detection statistics from cache.
183
+ *
184
+ * @returns Statistics about cached detections
185
+ */
186
+ getCacheStatistics() {
187
+ let serviceEntries = 0;
188
+ let nonServiceEntries = 0;
189
+ for (const result of this.cache.values()) {
190
+ if (result.isService) {
191
+ serviceEntries++;
192
+ }
193
+ else {
194
+ nonServiceEntries++;
195
+ }
196
+ }
197
+ return {
198
+ totalEntries: this.cache.size,
199
+ serviceEntries,
200
+ nonServiceEntries,
201
+ };
202
+ }
203
+ /**
204
+ * Clear the detection cache.
205
+ *
206
+ * Call this when the AST has been modified and cached results
207
+ * may be stale.
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * // After modifying files
212
+ * await project.save();
213
+ * detector.clearCache();
214
+ * ```
215
+ */
216
+ clearCache() {
217
+ this.cache.clear();
218
+ }
219
+ /**
220
+ * Get cache key for a class declaration.
221
+ *
222
+ * @param classDecl - The class declaration
223
+ * @returns Cache key string
224
+ */
225
+ getCacheKey(classDecl) {
226
+ const filePath = classDecl.getSourceFile().getFilePath();
227
+ const className = classDecl.getName() ?? 'anonymous';
228
+ return `${filePath}:${className}`;
229
+ }
230
+ }
231
+ //# sourceMappingURL=service-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-detector.js","sourceRoot":"","sources":["../../src/analysis/service-detector.ts"],"names":[],"mappings":"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"}