Skip to content

Comments

feat: strengthen type safety and module boundaries#351

Open
Chemaclass wants to merge 9 commits intomainfrom
feat/type-safety-and-boundaries
Open

feat: strengthen type safety and module boundaries#351
Chemaclass wants to merge 9 commits intomainfrom
feat/type-safety-and-boundaries

Conversation

@Chemaclass
Copy link
Member

@Chemaclass Chemaclass commented Feb 13, 2026

TL;DR

Introduces stricter type safety through interface segregation, generic types, and PHPStan rules to enforce module boundaries and explicit dependency declarations.

Summary

  • Add interface segregation for AbstractFactory (ConfigAccessorInterface, ProviderAccessorInterface, ServiceFactoryInterface)
  • Implement PHPStan rules for module boundary enforcement with automated analysis commands
  • Strengthen type safety with stricter generics across the framework
  • Add explicit module dependency declaration interface with version compatibility checking
  • Include comprehensive tests and documentation for all new features

Key Changes

New Interfaces:

  • ConfigAccessorInterface - Access to module configuration
  • ProviderAccessorInterface - Access to dependency providers
  • ServiceFactoryInterface - Access to service factories

New Commands:

  • analyze:dependencies - Analyze module dependencies with multiple output formats
  • version:check - Check module version compatibility

PHPStan Integration:

  • Module boundary rules with comprehensive documentation
  • Automated dependency analysis
  • Support for Graphviz, Mermaid, and JSON output formats

Dependency Management:

  • Module version compatibility checker
  • YAML and array-based version parsers
  • Explicit dependency declaration through interfaces

Infrastructure:

  • Event bus for module communication
  • Dependency analyzer supporting multiple visualization formats
  • Comprehensive test coverage

Split AbstractFactory responsibilities into focused interfaces:
- ServiceFactoryInterface: for managing service singletons
- ConfigAccessorInterface: for accessing module configuration
- ProviderAccessorInterface: for accessing provided dependencies

This improves separation of concerns and enables more flexible architecture patterns.
Implement PHPStan extension to enforce module boundaries and prevent direct
cross-module access to Domain and Infrastructure classes. Modules can now only
communicate through Facades, ensuring better encapsulation and maintainability.
Enhanced generic type hints across core framework classes:
- Added @template with return type constraints for better type inference
- Improved AbstractFacade with @psalm-consistent-constructor
- Enhanced singleton() with callable return type specification
- Added @psalm-return annotations for PHPStan/Psalm
- Strengthened generic bounds in AbstractFactory and AbstractProvider
- Updated all interface contracts with template generics

This enables better IDE autocomplete and static analysis for module development.
Added ModuleDependenciesInterface and dependencies() method to AbstractFacade:
- New ModuleDependenciesInterface for declaring inter-module dependencies
- Default empty implementation in AbstractFacade
- Returns array of facade class names that the module depends on
- Enables dependency graph visualization and circular dependency detection

Modules can now override dependencies() to explicitly declare their dependencies.
@Chemaclass Chemaclass force-pushed the feat/type-safety-and-boundaries branch from cd1894d to 7237016 Compare February 13, 2026 10:28
- Add return type annotation to arrow function in Container.php lazy services
- Fix preg_match conditions to explicitly check === 1 in ModuleBoundaryRule
- Remove deleted Event classes references from multiple files:
  - PhpConfigReader, DocBlockResolverCache, ClassResolverCache
  - AbstractClassResolver, ClassNameFinder
  - SetupMerger, Config
- Add template parameter specifications for generic classes:
  - AbstractFacade<AbstractFactory<AbstractConfig>>
  - AbstractProvider<AbstractConfig>
- Remove template TDependency from ProviderAccessorInterface (non-inferrable)
- Regenerate Psalm baseline after all fixes

Note: Additional event dispatcher cleanup needed in Setup classes
- Delete SetupEventDispatcher.php
- Remove event properties from Properties, SetupGacela, SetupGacelaInterface
- Remove event methods: getEventDispatcher, setEventDispatcher, get/setGenericListeners, get/setSpecificListeners, canCreateEventDispatcher
- Remove event properties from GacelaConfig and GacelaConfigTransfer
- Remove event registration methods from GacelaConfig
- Remove event constants from AbstractSetupGacela

Note: 23 PHPStan errors remain, mainly type covariance issues
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant