-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Problem
Circular dependencies create maintenance challenges and can indicate poor architectural design. RefakTS currently lacks automated detection for:
- File-level circular dependencies - Files that import each other directly or indirectly
- Directory-level circular dependencies - Directories that depend on each other
- Class-level circular dependencies - Classes with circular references
These dependencies can lead to:
- Build issues and import ordering problems
- Testing difficulties and mocking complexity
- Tight coupling that makes refactoring harder
- Architectural erosion over time
Proposed Solution
Create a comprehensive circular dependency quality check that:
Detection Levels
1. File-Level Circular Dependencies
❌ BAD: A.ts → B.ts → C.ts → A.ts
✅ GOOD: A.ts → B.ts → C.ts (no cycles)
2. Directory-Level Circular Dependencies
❌ BAD:
src/core/commands/ → src/core/services/ → src/core/commands/
src/core/ → src/command-line-parser/ → src/core/
✅ GOOD: Hierarchical dependencies only
3. Class-Level Circular Dependencies
// ❌ BAD: Circular class dependencies
class A {
constructor(private b: B) {}
}
class B {
constructor(private a: A) {}
}
// ✅ GOOD: Dependency inversion
interface IB { doSomething(): void; }
class A {
constructor(private b: IB) {}
}
class B implements IB {
doSomething(): void {}
}Dependency Inversion Guidance
When circular dependencies are detected, suggest dependency inversion solutions:
- Extract interfaces to break circular references
- Introduce abstractions at dependency boundaries
- Use dependency injection patterns
- Apply observer patterns for loose coupling
Implementation Approach
Detection Algorithm
- Build dependency graph from import/export analysis
- Apply cycle detection (e.g., depth-first search with cycle tracking)
- Report circular paths with specific file/class chains
- Suggest solutions based on dependency inversion patterns
Directory-Level Analysis
Treat each directory as a logical unit and detect cycles at the directory level:
src/core/commands/ ↔ src/core/services/ # ❌ Circular
src/core/ ↔ src/command-line-parser/ # ❌ Circular
src/core/ → src/command-line-parser/ # ✅ Unidirectional
Quality Check Output
🚨 Circular Dependencies Detected:
File-level cycles:
• src/core/ast/location-range.ts → src/core/services/ast-service.ts → src/core/ast/location-range.ts
Directory-level cycles:
• src/core/commands/ ↔ src/core/services/
Suggested fixes:
• Extract interface from ASTService to break location-range cycle
• Move shared abstractions to src/core/interfaces/Advanced Features (Optional Discussion)
Explicit Dependency Direction Enforcement
Question for consideration: Should we enforce specific dependency directions?
Examples:
- Commands → Services → AST (never reverse)
- Core → CLI (never CLI → Core)
- Tests → Source (never Source → Tests)
Benefits: Clearer architecture, prevention of architectural drift
Drawbacks: May be overly restrictive, harder to implement
Recommendation: Start with cycle detection, consider direction enforcement later if needed.
Implementation Steps
- Build dependency graph analyzer
- Parse import/export statements
- Track file-to-file dependencies
- Group files by directory
- Implement cycle detection algorithms
- File-level cycle detection
- Directory-level cycle detection
- Class-level dependency analysis
- Create quality check integration
- Integrate with existing quality check system
- Generate actionable error messages
- Suggest dependency inversion solutions
- Add configuration options
- Enable/disable different levels of checking
- Configure directory grouping rules
- Set cycle detection depth limits
Testing Strategy
Test Cases Needed
- Simple circular imports (A → B → A)
- Complex circular chains (A → B → C → D → A)
- Directory-level cycles with multiple files
- Valid dependency hierarchies (should not trigger)
- Dependency inversion examples (should not trigger)
Integration Points
- Post-commit hooks - Detect cycles in changed files
- CI/CD pipeline - Prevent merging cycle-introducing changes
- Development workflow - Real-time feedback during development
- Architecture reviews - Generate dependency reports
Priority
Medium - Architectural quality improvement that prevents technical debt accumulation.
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com