/** * @angular-modernizer/plugin-angular - Two Tier Instantiation Detector */ import { type NewExpression, type Project } from 'ts-morph'; /** * Configuration for TwoTierInstantiationDetector. * * Tier 1 checks are performed first (fast, name-based). * Tier 2 checks are performed only when Tier 1 yields no result (slow, AST-based). */ export interface TwoTierDetectorConfig { /** Tier 1: regex patterns (or strings compiled to RegExp) matched against the class name. */ classNamePatterns: (string | RegExp)[]; /** Tier 1: exact class names for a fast O(1) set lookup. */ explicitClassNames: string[]; /** Tier 2: names in the direct `extends` clause to check after resolving the import. */ baseClassNames: string[]; /** Tier 2: decorator names to check after resolving the import. */ decoratorNames: string[]; } /** * Result returned when an instantiation is detected. */ export interface TwoTierDetectionResult { /** Always `true` when a result is returned (non-null). */ matched: boolean; /** Which tier produced the match. */ tier: 1 | 2; /** The specific mechanism that triggered the match. */ mechanism: 'classNamePattern' | 'explicitClassName' | 'baseClass' | 'decorator'; /** The extracted class name from the `NewExpression`. */ className: string; } /** * Detects whether a `new X()` expression instantiates a class that matches * a two-tier configuration. * * Tier 1 — name-based (fast, no AST traversal): * - Exact name match via `explicitClassNames` * - Regex match via `classNamePatterns` * * Tier 2 — AST-based (slower, requires import resolution): * - Base class check via `baseClassNames` * - Decorator check via `decoratorNames` * * Short-circuits: if Tier 1 matches, Tier 2 is never invoked. * Fails gracefully: unresolvable imports and barrel re-exports return `null`. * * @example * ```typescript * const detector = new TwoTierInstantiationDetector(); * const result = detector.detect(newExpr, config, project); * if (result) { * console.info(`${result.className} matched via ${result.mechanism} (tier ${result.tier})`); * } * ``` */ export declare class TwoTierInstantiationDetector { /** * Detects whether the given `NewExpression` matches the supplied config. * * @param newExpr - The ts-morph `NewExpression` node to inspect. * @param config - Detection configuration (Tier 1 + Tier 2 options). * @param project - The ts-morph `Project` used for import resolution in Tier 2. * @returns A `TwoTierDetectionResult` if a match was found, `null` otherwise. */ detect(newExpr: NewExpression, config: TwoTierDetectorConfig, project: Project): TwoTierDetectionResult | null; /** * Extracts the class name from a `NewExpression`. * * Handles: * - Simple `new Foo()` → `'Foo'` * - Namespace `new ns.Foo()` → `'Foo'` (rightmost identifier) * * @param newExpr - The `NewExpression` node. * @returns The class name string. */ private extractClassName; /** * Compiles an array of string-or-RegExp patterns to `RegExp` instances. * * @param patterns - Mixed array of strings and RegExp objects. * @returns Array of `RegExp` instances. */ private compilePatterns; /** * Runs Tier 1 detection (name-based, no import resolution). * * Checks `explicitClassNames` first (exact), then `classNamePatterns` (regex). * * @param className - The extracted class name. * @param config - Detection configuration. * @returns A result with `tier=1` if matched, `null` otherwise. */ private runTier1; /** * Runs Tier 2 detection (AST-based, requires import resolution). * * Resolves the class declaration via the import graph, then checks the * `extends` clause and decorator list against the config. * * @param newExpr - The `NewExpression` node (needed for source file context). * @param className - The extracted class name. * @param config - Detection configuration. * @param project - The ts-morph `Project` for source-file resolution. * @returns A result with `tier=2` if matched, `null` otherwise. */ private runTier2; /** * Resolves the `ClassDeclaration` for the given class name by following the * import declarations in the source file of `newExpr`. * * Returns `null` (silently) when: * - No matching import declaration is found (class may be locally defined — not an error case for Tier 2) * - The import module cannot be resolved (external package) * - The resolved source file does not directly declare the class (barrel re-export) * - Any unexpected ts-morph exception occurs * * @param newExpr - The `NewExpression` node whose source file is searched for imports. * @param className - The class name to resolve. * @param project - The ts-morph `Project` (unused directly — resolution goes via source file). * @returns The `ClassDeclaration` or `null`. */ private resolveClassDeclaration; } //# sourceMappingURL=two-tier-instantiation-detector.d.ts.map