Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Planned

* Shared dependency graph compilation and analysis.
* Unified dependency candidate selection for static validation.
* Additional validation performance optimizations.

## [[v0.4.0](https://github.com/The-FireHub-Project/Container/compare/v0.3.0...v0.4.0)] – 2026-10-23

### Added
* Comprehensive static container validation through `Container::validate()` by @dieselxxx
* Structured validation results with issue types, severity levels, and dependency paths by @dieselxxx
* Constructor dependency graph validation, including missing dependencies and circular references by @dieselxxx
* Static validation of union, intersection, and disjunctive normal form (DNF) dependencies by @dieselxxx
* Tagged service and collection injection validation by @dieselxxx
* Explicit constructor parameter binding validation by @dieselxxx
* Contextual binding validation, including implementation compatibility and unused bindings by @dieselxxx
* Singleton-to-scoped lifetime mismatch detection for direct and transitive dependencies by @dieselxxx
* Lifetime validation supports for contextual, composite, tagged, collection, and aliased dependencies by @dieselxxx
* Runtime lifetime protection regression tests by @dieselxxx
* Shared constructor metadata, dependency plan, and type-matching caches across validation stages by @dieselxxx
* Canonical service identifier caching for alias resolution by @dieselxxx
* Expanded PHPUnit coverage for dependency validation and service lifetime behavior by @dieselxxx

### Changed
* Consolidated constructor metadata analysis across validation components by @dieselxxx
* Reduced redundant reflection and dependency plan compilation during validation by @dieselxxx
* Improved consistency between static dependency analysis and runtime dependency resolution by @dieselxxx
* Optimized alias resolution through shared caching within individual validation operations by @dieselxxx

## [[v0.3.0](https://github.com/The-FireHub-Project/Container/compare/v0.2.0...v0.3.0)] – 2026-10-22

### Added
Expand Down
88 changes: 53 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/></a>
<a href="#">
<img
src="https://img.shields.io/badge/Version-0.3.0-d50000?style=flat&labelColor=30363d&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMzMuNjUxIDM4Ny4wOSI+CiAgICA8dGl0bGU+RmlyZWh1YiBJY29uPC90aXRsZT4KICAgIDxzdHlsZT4KICAgICAgICAuY29sb3Ige2ZpbGw6ICNkNTAwMDA7fQogICAgPC9zdHlsZT4KICAgIDxnPgogICAgICAgIDxwYXRoIGNsYXNzPSJjb2xvciIgZD0iTTI2Ny4xMDYsMjYyLjU2MWMxMC41LTE3LjYzMSwxOS42My0zNi45MzEsMjAuMTItNTcuNDUxYzAuNDktMjAuNTItOS42LTQyLjQxOS0yOC40Ni01MC41MmM1LjcxLDkuNjcsMTAuMjUsMjAuNjIsOS4yOCwzMS44MWMtMC45NywxMS4xOS04Ljg2LDIyLjM3LTIwLDI0Yy0xMC40OSwxLjUyOS0yMC43Ny01Ljg1MS0yNS41MS0xNS4zNGMtNC43NC05LjQ5MS00LjYyLTIwLjU2MS00LTMxLjE1QzIyNC4zOTYsNTYuMTcsMTQyLjA0Niw1Ljk0LDEyNy4yODYsMGMwLDAsMTEuNDksMTIuMzksMTMuODgsMzAuNTNjMS45LDE0LjQ0LDAuMTcsMjkuMjItMy4zNCw0My4yNGMtMTAuODgsNDMuMzUtMzYuODYsNzcuODItNTguNTksMTE2Yy0xNC41OCwyNS41OC0yNCw1NC4wNS0yMy4zMiw4My42OWMwLjc2LDM0LDE2LDY3LjksNDIuNzMsODguODdjMTMuMDUsMTAuMjI5LDI4LjMyLDE3LjY1LDQzLjg0LDIzLjI5Yy0yLjE5LTIuNjItNC44NS01LjYyLTctOC42MDFjLTE4LjY4LTI1LjkzOS0zMi4yNi01MS41LTMzLjE3LTg0LjEwOWMtMC43Ny0yOC4yMyw3LjQtNTMuOTMsMTUuMTQtODAuNjFjLTAuOTEsMy4xNCwxLjgzLDEwLjcsMi4xLDE0LjIxYzAuNDEsNS40LDAuNDYsMTAuODIsMC41LDE2LjIyMWMwLjA4LDExLjQ3LTAuMTQsMjMsMS4zMiwzNC4zNzljMy40MiwyNi43NCwxOC4yOCw0OS43MTEsNDMuMjYsNjEuMjAxYy04LjQ3LTE5LjY5LTkuMzEtMzYuMzAxLTEuMjgtNTYuNzIxYzYuMDUtMTUuMzY5LDE0LjcxLTI5Ljc3OSwxOC45NC00NS43NWM4LjYzLTMyLjU2LTIuNDItNjcuNjQtMjAuNzUtOTUuODljMTcuMzIsMTUuMzEsMzIsMzQuNDUsMzguMyw1Ni43YzcuMzYsMjYsMi44Niw1My41NiwwLDgwLjM5Yy0yLjUxLDIzLjIxLTMuNzEsNDgsNS40Miw3MC4wNWM4LDE5LjIzLDIyLjQsMjkuNTIxLDM5LjUxLDQwYy0zLjY0NC0zLjAxMS02LjU2Ni02LjgtOC41NS0xMS4wOWMtOS4xNi0xOC4zNy02LjczLTQwLjY2LDAuNzktNTkuNzZTMjU2LjYxNiwyODAuMiwyNjcuMTA2LDI2Mi41NjF6Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNvbG9yIiBkPSJNMTczLjEzNiwyMi40M2M1LjA3OCw0Ljk5MSw5Ljg3MiwxMC4yNjIsMTQuMzYsMTUuNzljMS43NzMsMi4xODcsMy40ODMsNC40LDUuMTMsNi42NGM3OS42NzQsMTQuMjQ0LDEzMi43MTYsOTAuMzgsMTE4LjQ3MiwxNzAuMDU0Yy02Ljk0NywzOC44NTctMjkuMjc2LDczLjI3LTYxLjkzMiw5NS40NDZjLTEuNDMsMy0yLjc3LDYtNCw5Yy0yLjUyOCw2LjM3Ny00LjMzLDEzLjAxOS01LjM3LDE5LjhjODIuODQ5LTQwLjMyOSwxMTcuMzE4LTE0MC4xODUsNzYuOTg5LTIyMy4wMzNDMjg5Ljg0OSw2MC43OSwyMzQuNjM1LDI0Ljc3NywxNzMuMTM2LDIyLjQzeiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjb2xvciIgZD0iTTQ3LjA0NiwyNzMuNjA5di0wLjA4QzAuNDM1LDIwNy4zNTQsMTYuMjk2LDExNS45MjMsODIuNDcxLDY5LjMxM2MxNS4yNTQtMTAuNzQ0LDMyLjQyLTE4LjQ3Nyw1MC41NzUtMjIuNzgzYzAuMjEyLTQuOTYyLDAuMDA1LTkuOTMzLTAuNjItMTQuODZjLTAuMjUzLTEuODc1LTAuNjI0LTMuNzMxLTEuMTEtNS41NkM0MS4yOTksNDUuNzM4LTE1Ljc2MywxMzQuNjIzLDMuODY1LDIyNC42NGM3LjI4LDMzLjM5LDI0LjY0LDYzLjczOCw0OS43MzEsODYuOTRDNDkuNTU5LDI5OS4zMTQsNDcuMzUyLDI4Ni41Miw0Ny4wNDYsMjczLjYwOXoiLz4KICAgIDwvZz4KPC9zdmc+"
src="https://img.shields.io/badge/Version-0.4.0-d50000?style=flat&labelColor=30363d&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMzMuNjUxIDM4Ny4wOSI+CiAgICA8dGl0bGU+RmlyZWh1YiBJY29uPC90aXRsZT4KICAgIDxzdHlsZT4KICAgICAgICAuY29sb3Ige2ZpbGw6ICNkNTAwMDA7fQogICAgPC9zdHlsZT4KICAgIDxnPgogICAgICAgIDxwYXRoIGNsYXNzPSJjb2xvciIgZD0iTTI2Ny4xMDYsMjYyLjU2MWMxMC41LTE3LjYzMSwxOS42My0zNi45MzEsMjAuMTItNTcuNDUxYzAuNDktMjAuNTItOS42LTQyLjQxOS0yOC40Ni01MC41MmM1LjcxLDkuNjcsMTAuMjUsMjAuNjIsOS4yOCwzMS44MWMtMC45NywxMS4xOS04Ljg2LDIyLjM3LTIwLDI0Yy0xMC40OSwxLjUyOS0yMC43Ny01Ljg1MS0yNS41MS0xNS4zNGMtNC43NC05LjQ5MS00LjYyLTIwLjU2MS00LTMxLjE1QzIyNC4zOTYsNTYuMTcsMTQyLjA0Niw1Ljk0LDEyNy4yODYsMGMwLDAsMTEuNDksMTIuMzksMTMuODgsMzAuNTNjMS45LDE0LjQ0LDAuMTcsMjkuMjItMy4zNCw0My4yNGMtMTAuODgsNDMuMzUtMzYuODYsNzcuODItNTguNTksMTE2Yy0xNC41OCwyNS41OC0yNCw1NC4wNS0yMy4zMiw4My42OWMwLjc2LDM0LDE2LDY3LjksNDIuNzMsODguODdjMTMuMDUsMTAuMjI5LDI4LjMyLDE3LjY1LDQzLjg0LDIzLjI5Yy0yLjE5LTIuNjItNC44NS01LjYyLTctOC42MDFjLTE4LjY4LTI1LjkzOS0zMi4yNi01MS41LTMzLjE3LTg0LjEwOWMtMC43Ny0yOC4yMyw3LjQtNTMuOTMsMTUuMTQtODAuNjFjLTAuOTEsMy4xNCwxLjgzLDEwLjcsMi4xLDE0LjIxYzAuNDEsNS40LDAuNDYsMTAuODIsMC41LDE2LjIyMWMwLjA4LDExLjQ3LTAuMTQsMjMsMS4zMiwzNC4zNzljMy40MiwyNi43NCwxOC4yOCw0OS43MTEsNDMuMjYsNjEuMjAxYy04LjQ3LTE5LjY5LTkuMzEtMzYuMzAxLTEuMjgtNTYuNzIxYzYuMDUtMTUuMzY5LDE0LjcxLTI5Ljc3OSwxOC45NC00NS43NWM4LjYzLTMyLjU2LTIuNDItNjcuNjQtMjAuNzUtOTUuODljMTcuMzIsMTUuMzEsMzIsMzQuNDUsMzguMyw1Ni43YzcuMzYsMjYsMi44Niw1My41NiwwLDgwLjM5Yy0yLjUxLDIzLjIxLTMuNzEsNDgsNS40Miw3MC4wNWM4LDE5LjIzLDIyLjQsMjkuNTIxLDM5LjUxLDQwYy0zLjY0NC0zLjAxMS02LjU2Ni02LjgtOC41NS0xMS4wOWMtOS4xNi0xOC4zNy02LjczLTQwLjY2LDAuNzktNTkuNzZTMjU2LjYxNiwyODAuMiwyNjcuMTA2LDI2Mi41NjF6Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNvbG9yIiBkPSJNMTczLjEzNiwyMi40M2M1LjA3OCw0Ljk5MSw5Ljg3MiwxMC4yNjIsMTQuMzYsMTUuNzljMS43NzMsMi4xODcsMy40ODMsNC40LDUuMTMsNi42NGM3OS42NzQsMTQuMjQ0LDEzMi43MTYsOTAuMzgsMTE4LjQ3MiwxNzAuMDU0Yy02Ljk0NywzOC44NTctMjkuMjc2LDczLjI3LTYxLjkzMiw5NS40NDZjLTEuNDMsMy0yLjc3LDYtNCw5Yy0yLjUyOCw2LjM3Ny00LjMzLDEzLjAxOS01LjM3LDE5LjhjODIuODQ5LTQwLjMyOSwxMTcuMzE4LTE0MC4xODUsNzYuOTg5LTIyMy4wMzNDMjg5Ljg0OSw2MC43OSwyMzQuNjM1LDI0Ljc3NywxNzMuMTM2LDIyLjQzeiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjb2xvciIgZD0iTTQ3LjA0NiwyNzMuNjA5di0wLjA4QzAuNDM1LDIwNy4zNTQsMTYuMjk2LDExNS45MjMsODIuNDcxLDY5LjMxM2MxNS4yNTQtMTAuNzQ0LDMyLjQyLTE4LjQ3Nyw1MC41NzUtMjIuNzgzYzAuMjEyLTQuOTYyLDAuMDA1LTkuOTMzLTAuNjItMTQuODZjLTAuMjUzLTEuODc1LTAuNjI0LTMuNzMxLTEuMTEtNS41NkM0MS4yOTksNDUuNzM4LTE1Ljc2MywxMzQuNjIzLDMuODY1LDIyNC42NGM3LjI4LDMzLjM5LDI0LjY0LDYzLjczOCw0OS43MzEsODYuOTRDNDkuNTU5LDI5OS4zMTQsNDcuMzUyLDI4Ni41Miw0Ny4wNDYsMjczLjYwOXoiLz4KICAgIDwvZz4KPC9zdmc+"
alt="version"
/></a>
<a href="./LICENSE">
Expand All @@ -22,10 +22,6 @@
/></a>
</h1>

[![PHPStan](https://github.com/The-FireHub-Project/Container/actions/workflows/PHPStan.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Container/actions/workflows/PHPStan.yml)
[![PHPUnit](https://github.com/The-FireHub-Project/Container/actions/workflows/PHPUnit.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Container/actions/workflows/PHPUnit.yml)
[![Codecov](https://codecov.io/gh/The-FireHub-Project/Container/branch/develop/graph/badge.svg?token=XW2YEONF51)](https://app.codecov.io/gh/The-FireHub-Project/Container/tree/develop)

<p>
<a href="https://github.com/The-FireHub-Project/Container">
<img
Expand Down Expand Up @@ -77,47 +73,69 @@ This repository serves as a foundational runtime component for FireHub applicati

---

## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Development Branch
## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Repository Purpose

FireHub Container is the dependency injection and service resolution component of the FireHub ecosystem.

Built on the contracts provided by FireHub Core, it supplies the mechanisms required to register, construct, resolve, and manage application services.

The purpose of this repository is to centralize dependency management while preserving separation of concerns between service definitions, runtime implementation, and application execution.

⚠️ **This is the `develop` branch**
The Container architecture is designed to support:

- Unstable
- APIs may change without notice
- Not intended for production use
- Service registration and dependency resolution
- Interface-to-implementation bindings
- Instance, factory, and class-based service definitions
- Singleton and transient service lifetimes
- Dependency graph resolution and circular dependency detection
- Immutable service registrations after container construction
- Future support for autowiring and execution-scoped services

## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Branch Purpose
FireHub Container follows the architectural principles of The FireHub Project by separating responsibilities between contracts, dependency management, and application lifecycle orchestration.

The `develop` branch is the **primary integration branch** for all ongoing development.
The Container does not control application execution or kernel lifecycle transitions. Instead, it provides dependency management services that can be integrated into applications through the appropriate bootstrap and composition mechanisms.

It serves as the staging area where:
- Feature branches are merged
- Bug fixes are integrated
- Experimental work is stabilized
- Code is prepared for upcoming releases
## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Security

All **release branches** are created **from `develop`**.
For security reporting and guidelines, please refer to our [SECURITY.md](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file.

## Stability Guarantee
## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Community

❌ No backward compatibility guarantee
❌ APIs may change without notice
❌ Behavior may be incomplete or inconsistent
❌ Breaking changes are expected
![GitHub watchers](https://img.shields.io/github/watchers/The-FireHub-Project/Container?style=social)
![GitHub Repo stars](https://img.shields.io/github/stars/The-FireHub-Project/Container?style=social)
![GitHub forks](https://img.shields.io/github/forks/The-FireHub-Project/Container?style=social)

This branch is intended **only for contributors and advanced testers**.
- Be sure to review the [Code of Conduct](https://github.com/The-FireHub-Project/.github/blob/master/.github/CODE_OF_CONDUCT.md).
- Read a [Contributing](https://github.com/The-FireHub-Project/.github/blob/master/.github/CONTRIBUTING.md) file to see how you can contribute to this project.
- Read our [Security policy](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file to see how you can report a vulnerability.
- Review the project [Governance model](https://github.com/The-FireHub-Project/.github/blob/master/.github/GOVERNANCE.md), including roles, decision-making, RFC process, and releases.

## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Composer Usage (Not Recommended)
## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Support

<p>
<a href="https://github.com/The-FireHub-Project/Container/issues?q=is%3Aissue%20state%3Aopen">
<img
src="https://img.shields.io/github/issues/The-FireHub-Project/Container?style=flat&logo=github&logoColor=959da5&label=in%20progress%20issues&labelColor=31373e"
alt="GitHub in-progress issues"
/></a>
<a href="https://github.com/The-FireHub-Project/Container/issues?q=is%3Aissue">
<img
src="https://img.shields.io/github/issues-search?query=repo%3AThe-FireHub-Project%Foundaton&style=flat&logo=github&logoColor=959da5&label=total%20issues&labelColor=31373e"
alt="GitHub total issues"
/></a>
<a href="https://github.com/The-FireHub-Project/Container/issues?q=is%3Apr%20is%3Aopen">
<img
src="https://img.shields.io/github/issues-pr/The-FireHub-Project/Container?style=flat&logo=github&logoColor=959da5&labelColor=31373e"
alt="GitHub opened pull requests"
/></a>
</p>

For internal testing only:
For help with FireHub products, please refer to the following resources:

```json
{
"require": {
"the-firehub-project/container": "dev-develop"
}
}
```
⚠️ Never use dev-develop in production.
- **General questions & discussions**: [GitHub Discussions](https://github.com/orgs/The-FireHub-Project/discussions)
- **Bug reports & issues**: [Support](https://github.com/The-FireHub-Project/Container/issues)
- **Documentation & guides**: [FireHub Docs](https://the-firehub-project.github.io)
- **Commercial support** (Pro/Enterprise): contact your account manager

## <img src="https://raw.githubusercontent.com/The-FireHub-Project/the-firehub-project.github.io/master/resources/graphics/icons/firehub.svg" width="15" alt="FireHub Icon"> Authors and Contributors

Expand All @@ -134,4 +152,4 @@ Architecture guidelines, design principles, and ecosystem documentation are avai

This software is licensed under the Apache-2.0 License.

For more details, read the full license [here](./LICENSE).
For more details, read the full license [here](./LICENSE).
30 changes: 30 additions & 0 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
ContainerState, ContextualBindingRegistry, DisposalTracker, InstanceStore, ParameterBindingRegistry,
ResolutionContext, ScopeRegistry, TagRegistry
};
use FireHub\Container\Validation\Result;
use FireHub\Container\Exception\ {
ContainerActiveScopesException, InvalidTagNameException, ServiceNotFoundException
};
Expand Down Expand Up @@ -1213,4 +1214,33 @@ public function isFrozen ():bool {

}

/**
* ### Validates registered service definitions
*
* Performs static validation of the container configuration without instantiating services or executing factory
* callbacks.
*
* Validation does not freeze or modify the container.
* @since 1.0.0
*
* @uses \FireHub\Container\Validation::validate() To validate registered service definitions.
*
* @throws \FireHub\Container\Exception\ServiceInstantiationException If a constructor parameter contains invalid
* injection attributes or unsupported dependency metadata.
* @throws \FireHub\Container\Exception\AmbiguousDependencyException If multiple candidates are eligible.
* @throws \FireHub\Container\Exception\ServiceInstantiationException If the composite type is unsupported.
*
* @return \FireHub\Container\Validation\Result Container validation result.
*/
public function validate ():Result {

return new Validator(
$this->registry,
$this->parameters,
$this->contextual,
$this->tags
)->validate();

}

}
132 changes: 132 additions & 0 deletions src/Internal/CanonicalIdCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php declare(strict_types = 1);

/**
* This file is part of the FireHub Project ecosystem
*
* @author Danijel Galić <danijel.galic@outlook.com>
* @copyright 2026-present The FireHub Project - All rights reserved
* @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0
*
* @php-version >=8.2
* @package Container
*/

namespace FireHub\Container\Internal;

use FireHub\Container\Registry;
use FireHub\Container\Definition\Alias;
use FireHub\Runtime;

/**
* ### Caches canonical service identifiers
*
* Resolves registered alias chains to their final service identifiers.
*
* Successfully resolved identifiers and invalid alias chains are cached for reuse throughout a single container
* validation operation.
*
* Circular and unresolved aliases return null.
*
* The cache assumes that service registrations remain unchanged during its lifetime.
* @since 1.0.0
*
* @internal
*/
final class CanonicalIdCache {

/**
* ### Cached canonical identifiers
* @since 1.0.0
*
* @var array<class-string, null|class-string>
*/
private array $cache = [];

/**
* ### Constructor
* @since 1.0.0
*
* @param \FireHub\Container\Registry $registry <p>
* Registered service definitions.
* </p>
*/
public function __construct (

Check warning on line 53 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L53

Added line #L53 was not covered by tests
private readonly Registry $registry
) {}

Check warning on line 55 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L55

Added line #L55 was not covered by tests

/**
* ### Gets the canonical service identifier
*
* Follows alias chains and caches their resolved targets.
*
* Invalid and circular alias chains are cached as null.
* @since 1.0.0
*
* @uses \FireHub\Container\Registry::find() To retrieve a service definition.
* @uses \FireHub\Container\Registry::has() To check if an alias target exists.
* @uses \FireHub\Runtime\Arr\Access::keyExists() To check if a key exists in an array.
*
* @param class-string $id <p>
* Service identifier.
* </p>
*
* @return null|class-string Canonical service identifier.
*/
public function get (string $id):?string {

Check warning on line 75 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L75

Added line #L75 was not covered by tests

if (Runtime\Arr\Access::keyExists($this->cache, $id))
return $this->cache[$id]; // @phpstan-ignore offsetAccess.notFound

Check warning on line 78 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L77-L78

Added lines #L77 - L78 were not covered by tests

$visited = []; $path = []; $current = $id;
while (true) {

Check warning on line 81 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L80-L81

Added lines #L80 - L81 were not covered by tests

if (Runtime\Arr\Access::keyExists($this->cache, $id)) { // @phpstan-ignore if.alwaysFalse

Check warning on line 83 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L83

Added line #L83 was not covered by tests

$canonical = $this->cache[$current]; // @phpstan-ignore offsetAccess.notFound

Check warning on line 85 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L85

Added line #L85 was not covered by tests

break;

Check warning on line 87 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L87

Added line #L87 was not covered by tests

}

if (isset($visited[$current])) {

Check warning on line 91 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L91

Added line #L91 was not covered by tests

$canonical = null;

Check warning on line 93 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L93

Added line #L93 was not covered by tests

break;

Check warning on line 95 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L95

Added line #L95 was not covered by tests

}

$visited[$current] = true;

Check warning on line 99 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L99

Added line #L99 was not covered by tests

$path[] = $current;

Check warning on line 101 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L101

Added line #L101 was not covered by tests

$definition = $this->registry->find($current);

Check warning on line 103 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L103

Added line #L103 was not covered by tests

if (!$definition instanceof Alias) {

Check warning on line 105 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L105

Added line #L105 was not covered by tests

$canonical = $current;

Check warning on line 107 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L107

Added line #L107 was not covered by tests

break;

Check warning on line 109 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L109

Added line #L109 was not covered by tests

}

$current = $definition->target;

Check warning on line 113 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L113

Added line #L113 was not covered by tests

if (!$this->registry->has($current)) {

Check warning on line 115 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L115

Added line #L115 was not covered by tests

$canonical = null;

Check warning on line 117 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L117

Added line #L117 was not covered by tests

break;

Check warning on line 119 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L119

Added line #L119 was not covered by tests

}

}

foreach ($path as $visited_id)
$this->cache[$visited_id] = $canonical;

Check warning on line 126 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L125-L126

Added lines #L125 - L126 were not covered by tests

return $canonical;

Check warning on line 128 in src/Internal/CanonicalIdCache.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/CanonicalIdCache.php#L128

Added line #L128 was not covered by tests

}

}
Loading
Loading