Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 3 additions & 0 deletions src/product/BillingRegistryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ interface BillingRegistryInterface extends HasLockInterface
*/
public function priceTypes(): Generator;

/**
* @return TariffTypeDefinitionInterface[]
*/
public function getTariffTypeDefinitions(): array;

public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void;
Expand Down
9 changes: 6 additions & 3 deletions src/product/TariffTypeDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function belongToTariffType(TariffTypeInterface $tariffType): bool
return $this->tariffType->equals($tariffType);
}

public function ofProduct(ProductInterface $product): TariffTypeDefinitionInterface
public function ofProduct(ProductInterface $product): static
{
$this->ensureNotLocked();
$this->product = $product;
Expand All @@ -61,7 +61,7 @@ private function ensureProductExists(): void
}
}

public function setPricesSuggester(string $suggesterClass): TariffTypeDefinitionInterface
public function setPricesSuggester(string $suggesterClass): static
{
$this->ensureNotLocked();

Expand All @@ -76,7 +76,10 @@ public function withPrices(): PriceTypeDefinitionCollection
return $this->prices;
}

public function withBehaviors(): BehaviorTariffTypeCollection
/**
* @return BehaviorTariffTypeCollection<TariffTypeDefinition>
*/
public function withBehaviors()
{
$this->ensureNotLocked();

Expand Down
13 changes: 6 additions & 7 deletions src/product/TariffTypeDefinitionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
use hiqdev\php\billing\product\trait\HasLockInterface;

/**
* @template T of PriceTypeDefinitionCollectionInterface
* @template-covariant T of PriceTypeDefinitionCollectionInterface
*/
interface TariffTypeDefinitionInterface extends HasBehaviorsInterface, HasLockInterface

Check failure on line 13 in src/product/TariffTypeDefinitionInterface.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

InvalidTemplateParam

src/product/TariffTypeDefinitionInterface.php:13:49: InvalidTemplateParam: Cannot extend a strictly-enforced parent template param TParentCollection with a non-template type (see https://psalm.dev/183)

Check failure on line 13 in src/product/TariffTypeDefinitionInterface.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

MissingTemplateParam

src/product/TariffTypeDefinitionInterface.php:13:49: MissingTemplateParam: hiqdev\php\billing\product\TariffTypeDefinitionInterface has missing template params when extending hiqdev\php\billing\product\behavior\HasBehaviorsInterface, expecting 1 (see https://psalm.dev/182)

Check failure on line 13 in src/product/TariffTypeDefinitionInterface.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

InvalidTemplateParam

src/product/TariffTypeDefinitionInterface.php:13:49: InvalidTemplateParam: Cannot extend a strictly-enforced parent template param TParentCollection with a non-template type (see https://psalm.dev/183)

Check failure on line 13 in src/product/TariffTypeDefinitionInterface.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

MissingTemplateParam

src/product/TariffTypeDefinitionInterface.php:13:49: MissingTemplateParam: hiqdev\php\billing\product\TariffTypeDefinitionInterface has missing template params when extending hiqdev\php\billing\product\behavior\HasBehaviorsInterface, expecting 1 (see https://psalm.dev/182)
{
public function tariffType(): TariffTypeInterface;

Expand All @@ -22,17 +22,16 @@
*/
public function belongToTariffType(TariffTypeInterface $tariffType): bool;

public function ofProduct(ProductInterface $product): self;
public function ofProduct(ProductInterface $product): static;

public function getProduct(): ProductInterface;

public function setPricesSuggester(string $suggesterClass): self;
public function setPricesSuggester(string $suggesterClass): static;

/**
* @return PriceTypeDefinitionCollectionInterface
* @psalm-return T
* @return T
*/
public function withPrices(): PriceTypeDefinitionCollectionInterface;
public function withPrices();

public function end(): self;
public function end();
}
7 changes: 6 additions & 1 deletion src/product/behavior/BehaviorCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface;
use hiqdev\php\billing\product\trait\HasLock;

/**
* @template TPriceDefinition
* @implements BehaviorCollectionInterface<TPriceDefinition>
* @psalm-consistent-templates
*/
abstract class BehaviorCollection implements BehaviorCollectionInterface

Check failure on line 13 in src/product/behavior/BehaviorCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

TooManyTemplateParams

src/product/behavior/BehaviorCollection.php:13:46: TooManyTemplateParams: hiqdev\php\billing\product\behavior\BehaviorCollection requires the same number of template params as hiqdev\php\billing\product\behavior\BehaviorCollectionInterface but saw 1 (see https://psalm.dev/184)

Check failure on line 13 in src/product/behavior/BehaviorCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

TooManyTemplateParams

src/product/behavior/BehaviorCollection.php:13:46: TooManyTemplateParams: hiqdev\php\billing\product\behavior\BehaviorCollection has too many template params when extending hiqdev\php\billing\product\behavior\BehaviorCollectionInterface, expecting 0 (see https://psalm.dev/184)

Check failure on line 13 in src/product/behavior/BehaviorCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

TooManyTemplateParams

src/product/behavior/BehaviorCollection.php:13:46: TooManyTemplateParams: hiqdev\php\billing\product\behavior\BehaviorCollection requires the same number of template params as hiqdev\php\billing\product\behavior\BehaviorCollectionInterface but saw 1 (see https://psalm.dev/184)

Check failure on line 13 in src/product/behavior/BehaviorCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

TooManyTemplateParams

src/product/behavior/BehaviorCollection.php:13:46: TooManyTemplateParams: hiqdev\php\billing\product\behavior\BehaviorCollection has too many template params when extending hiqdev\php\billing\product\behavior\BehaviorCollectionInterface, expecting 0 (see https://psalm.dev/184)
{
use HasLock;

Expand All @@ -21,7 +26,7 @@
return new \ArrayIterator($this->behaviors);
}

public function attach(BehaviorInterface $behavior): self
public function attach(BehaviorInterface $behavior): static
{
$this->ensureNotLocked();

Expand Down
8 changes: 3 additions & 5 deletions src/product/behavior/BehaviorCollectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

/**
* @extends IteratorAggregate<int, BehaviorInterface>
* @psalm-consistent-templates
*/
interface BehaviorCollectionInterface extends IteratorAggregate, HasLockInterface
{
Expand All @@ -18,10 +19,7 @@ interface BehaviorCollectionInterface extends IteratorAggregate, HasLockInterfac
*/
public function getIterator(): Traversable;

public function attach(BehaviorInterface $behavior): self;
public function attach(BehaviorInterface $behavior): static;

/**
* @return TariffTypeDefinitionInterface|PriceTypeDefinitionInterface
*/
public function end(): TariffTypeDefinitionInterface|PriceTypeDefinitionInterface;
public function end();
}
26 changes: 23 additions & 3 deletions src/product/behavior/BehaviorPriceTypeDefinitionCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,34 @@
use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface;
use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface;

/**
* @template TPriceDefinition
* @extends BehaviorCollection<TPriceDefinition>
* @psalm-consistent-templates
*/
class BehaviorPriceTypeDefinitionCollection extends BehaviorCollection
{
public function __construct(private readonly PriceTypeDefinitionInterface $parent, TariffTypeInterface $tariffType)
{
/**
* @psalm-var TPriceDefinition
*/
private readonly PriceTypeDefinitionInterface $parent;

/**
* @psalm-param TPriceDefinition $parent
*/
public function __construct(
PriceTypeDefinitionInterface $parent,
TariffTypeInterface $tariffType
) {
$this->parent = $parent;

parent::__construct($tariffType);
}

public function end(): PriceTypeDefinitionInterface
/**
* @return TPriceDefinition
*/
public function end()
{
return $this->parent;
}
Expand Down
18 changes: 16 additions & 2 deletions src/product/behavior/BehaviorTariffTypeCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@
use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface;
use hiqdev\php\billing\product\TariffTypeDefinitionInterface;

/**
* @template T
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Critical: Fix template parameter inheritance from parent class.

The static analysis failures indicate that BehaviorCollection (the parent class) has a template parameter that isn't being properly extended. You need to either:

  1. Pass the template parameter T to the parent class, or
  2. Ensure the parent class template requirements are satisfied.

Please run this script to examine the parent class template requirements:


🏁 Script executed:

#!/bin/bash
# Check the parent class BehaviorCollection template requirements
ast-grep --pattern 'abstract class BehaviorCollection {
  $$$
}'

# Also check for template annotations in BehaviorCollection
rg -A 5 -B 5 "@template" src/product/behavior/BehaviorCollection.php

Length of output: 453


Fix Generic Type Annotation in BehaviorTariffTypeCollection

The parent class BehaviorCollection is declared with a template parameter named TPriceDefinition. Your BehaviorTariffTypeCollection must match that name and pass it through to the parent:

• File: src/product/behavior/BehaviorTariffTypeCollection.php (lines 8–10)
– Change the docblock from:

/**
 * @template T
 */

to:

/**
 * @template TPriceDefinition
 */

• Update the class declaration to pass the template through:

final class BehaviorTariffTypeCollection
  extends BehaviorCollection<TPriceDefinition>
{
    // …
}

• Rename any occurrences of T in your constructor, end() method, or other generic annotations to TPriceDefinition.

These edits will align your child class’s generics with the parent’s @template TPriceDefinition and resolve the Psalm inheritance errors.

🤖 Prompt for AI Agents
In src/product/behavior/BehaviorTariffTypeCollection.php around lines 8 to 10,
the template parameter in the docblock is incorrectly named T instead of
matching the parent class BehaviorCollection's template parameter
TPriceDefinition. Update the docblock to use @template TPriceDefinition and
modify the class declaration to extend BehaviorCollection<TPriceDefinition>.
Also, rename any occurrences of T in the class's generic annotations, such as in
the constructor or methods, to TPriceDefinition to ensure proper template
inheritance and fix static analysis errors.

class BehaviorTariffTypeCollection extends BehaviorCollection

Check failure on line 11 in src/product/behavior/BehaviorTariffTypeCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

InvalidTemplateParam

src/product/behavior/BehaviorTariffTypeCollection.php:11:7: InvalidTemplateParam: Cannot extend a strictly-enforced parent template param TPriceDefinition with a non-template type (see https://psalm.dev/183)

Check failure on line 11 in src/product/behavior/BehaviorTariffTypeCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

MissingTemplateParam

src/product/behavior/BehaviorTariffTypeCollection.php:11:7: MissingTemplateParam: hiqdev\php\billing\product\behavior\BehaviorTariffTypeCollection has missing template params when extending hiqdev\php\billing\product\behavior\BehaviorCollection, expecting 1 (see https://psalm.dev/182)

Check failure on line 11 in src/product/behavior/BehaviorTariffTypeCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

InvalidTemplateParam

src/product/behavior/BehaviorTariffTypeCollection.php:11:7: InvalidTemplateParam: Cannot extend a strictly-enforced parent template param TPriceDefinition with a non-template type (see https://psalm.dev/183)

Check failure on line 11 in src/product/behavior/BehaviorTariffTypeCollection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3

MissingTemplateParam

src/product/behavior/BehaviorTariffTypeCollection.php:11:7: MissingTemplateParam: hiqdev\php\billing\product\behavior\BehaviorTariffTypeCollection has missing template params when extending hiqdev\php\billing\product\behavior\BehaviorCollection, expecting 1 (see https://psalm.dev/182)
{
public function __construct(private readonly TariffTypeDefinitionInterface $parent, TariffTypeInterface $tariffType)
{
/**
* @psalm-param T $parent
*/
public function __construct(
/**
* @var T
*/
private readonly TariffTypeDefinitionInterface $parent,
TariffTypeInterface $tariffType
) {
parent::__construct($tariffType);
}

/**
* @psalm-return T
*/
public function end(): TariffTypeDefinitionInterface
{
return $this->parent;
Expand Down
9 changes: 8 additions & 1 deletion src/product/behavior/HasBehaviorsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

namespace hiqdev\php\billing\product\behavior;

/**
* @template TParentCollection
* @psalm-consistent-templates
*/
interface HasBehaviorsInterface
{
public function withBehaviors(): BehaviorCollectionInterface;
// /**
// * @return BehaviorCollectionInterface<TParentCollection>
// */
// public function withBehaviors();

public function hasBehavior(string $behaviorClassName): bool;
}
11 changes: 11 additions & 0 deletions src/product/behavior/TariffTypeBehaviorRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,27 @@
* - To avoid code duplication of behavior-related methods in multiple classes.
* - To separate concerns by handling behavior-related logic in a dedicated class.
* - To improve maintainability and testability of tariff behavior handling.
*
* @template-covariant T of TariffTypeDefinitionInterface
*/
final class TariffTypeBehaviorRegistry implements HasLockInterface
{
/**
* @var BehaviorTariffTypeCollection<T>
*/
private BehaviorTariffTypeCollection $behaviorCollection;

/**
* @psalm-param T $tariffTypeDefinition
*/
public function __construct(TariffTypeDefinitionInterface $tariffTypeDefinition, TariffTypeInterface $tariffType)
{
$this->behaviorCollection = new BehaviorTariffTypeCollection($tariffTypeDefinition, $tariffType);
}

/**
* @return BehaviorTariffTypeCollection<T>
*/
public function getBehaviors(): BehaviorTariffTypeCollection
{
return $this->behaviorCollection;
Expand Down
21 changes: 16 additions & 5 deletions src/product/invoice/RepresentationCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
use Traversable;

/**
* @template T of PriceTypeDefinition
* @template T
* @implements IteratorAggregate<int, RepresentationInterface>
* @psalm-consistent-templates
*/
class RepresentationCollection implements IteratorAggregate, HasLockInterface
{
Expand All @@ -20,8 +21,18 @@ class RepresentationCollection implements IteratorAggregate, HasLockInterface

private RepresentationUniquenessGuard $uniquenessGuard;

public function __construct(private readonly PriceTypeDefinition $priceTypeDefinition)
{
/**
* @psalm-var T
*/
private readonly PriceTypeDefinition $priceTypeDefinition;

/**
* @psalm-param T $priceTypeDefinition
*/
public function __construct(
PriceTypeDefinition $priceTypeDefinition,
) {
$this->priceTypeDefinition = $priceTypeDefinition;
$this->uniquenessGuard = new RepresentationUniquenessGuard();
}

Expand All @@ -33,7 +44,7 @@ public function getIterator(): Traversable
return new \ArrayIterator($this->representations);
}

public function attach(RepresentationInterface $representation): self
public function attach(RepresentationInterface $representation): static
{
$this->ensureNotLocked();

Expand All @@ -49,7 +60,7 @@ public function attach(RepresentationInterface $representation): self
/**
* @psalm-return T
*/
public function end(): PriceTypeDefinition
public function end()
{
return $this->priceTypeDefinition;
}
Expand Down
Loading
Loading