diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php index d49901cc710..c1ba0f7539b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php @@ -66,6 +66,7 @@ use Psalm\Storage\Assertion\NonEmptyCountable; use Psalm\Storage\Assertion\NotNonEmptyCountable; use Psalm\Storage\Assertion\Truthy; +use Psalm\Storage\Possibilities; use Psalm\Storage\PropertyStorage; use Psalm\Type; use Psalm\Type\Atomic; @@ -803,10 +804,7 @@ public static function processFunctionCall( } } elseif ($class_exists_check_type = self::hasClassExistsCheck($expr)) { if ($first_var_name) { - $class_string_type = new TClassString(); - if ($class_exists_check_type === 1) { - $class_string_type->is_loaded = true; - } + $class_string_type = new TClassString('object', null, $class_exists_check_type === 1); $if_types[$first_var_name] = [[new IsType($class_string_type)]]; } } elseif ($class_exists_check_type = self::hasTraitExistsCheck($expr)) { @@ -819,14 +817,12 @@ public static function processFunctionCall( } } elseif (self::hasEnumExistsCheck($expr)) { if ($first_var_name) { - $class_string = new TClassString(); - $class_string->is_enum = true; + $class_string = new TClassString('object', null, false, false, true); $if_types[$first_var_name] = [[new IsType($class_string)]]; } } elseif (self::hasInterfaceExistsCheck($expr)) { if ($first_var_name) { - $class_string = new TClassString(); - $class_string->is_interface = true; + $class_string = new TClassString('object', null, false, true, false); $if_types[$first_var_name] = [[new IsType($class_string)]]; } } elseif (self::hasFunctionExistsCheck($expr)) { @@ -960,15 +956,15 @@ protected static function processCustomAssertion( foreach ($if_true_assertions as $assertion) { $if_types = []; - $assertion = clone $assertion; + $newRules = []; - foreach ($assertion->rule as $i => $rule) { + foreach ($assertion->rule as $rule) { $rule_type = $rule->getAtomicType(); if ($rule_type instanceof TClassConstant) { $codebase = $source->getCodebase(); - $assertion->rule[$i]->setAtomicType( + $newRules[] = $rule->setAtomicType( TypeExpander::expandAtomic( $codebase, $rule_type, @@ -977,9 +973,13 @@ protected static function processCustomAssertion( null )[0] ); + } else { + $newRules []= $rule; } } + $assertion = new Possibilities($assertion->var_id, $newRules); + if (is_int($assertion->var_id) && isset($expr->getArgs()[$assertion->var_id])) { if ($assertion->var_id === 0) { $var_name = $first_var_name; @@ -992,7 +992,7 @@ protected static function processCustomAssertion( } if ($var_name) { - $if_types[$var_name] = [[clone $assertion->rule[0]]]; + $if_types[$var_name] = [[$assertion->rule[0]]]; } } elseif ($assertion->var_id === '$this') { if (!$expr instanceof PhpParser\Node\Expr\MethodCall) { @@ -1012,7 +1012,7 @@ protected static function processCustomAssertion( ); if ($var_id) { - $if_types[$var_id] = [[clone $assertion->rule[0]]]; + $if_types[$var_id] = [[$assertion->rule[0]]]; } } elseif (is_string($assertion->var_id)) { $is_function = substr($assertion->var_id, -2) === '()'; @@ -1081,7 +1081,7 @@ protected static function processCustomAssertion( ); continue; } - $if_types[$assertion_var_id] = [[clone $assertion->rule[0]]]; + $if_types[$assertion_var_id] = [[$assertion->rule[0]]]; } if ($if_types) { @@ -1094,15 +1094,15 @@ protected static function processCustomAssertion( foreach ($if_false_assertions as $assertion) { $if_types = []; - $assertion = clone $assertion; + $newRules = []; - foreach ($assertion->rule as $i => $rule) { + foreach ($assertion->rule as $rule) { $rule_type = $rule->getAtomicType(); if ($rule_type instanceof TClassConstant) { $codebase = $source->getCodebase(); - $assertion->rule[$i]->setAtomicType( + $newRules []= $rule->setAtomicType( TypeExpander::expandAtomic( $codebase, $rule_type, @@ -1111,9 +1111,13 @@ protected static function processCustomAssertion( null )[0] ); + } else { + $newRules []= $rule; } } + $assertion = new Possibilities($assertion->var_id, $newRules); + if (is_int($assertion->var_id) && isset($expr->getArgs()[$assertion->var_id])) { if ($assertion->var_id === 0) { $var_name = $first_var_name; @@ -1126,7 +1130,7 @@ protected static function processCustomAssertion( } if ($var_name) { - $if_types[$var_name] = [[clone $assertion->rule[0]->getNegation()]]; + $if_types[$var_name] = [[$assertion->rule[0]->getNegation()]]; } } elseif ($assertion->var_id === '$this' && $expr instanceof PhpParser\Node\Expr\MethodCall) { $var_id = ExpressionIdentifier::getExtendedVarId( @@ -1136,7 +1140,7 @@ protected static function processCustomAssertion( ); if ($var_id) { - $if_types[$var_id] = [[clone $assertion->rule[0]->getNegation()]]; + $if_types[$var_id] = [[$assertion->rule[0]->getNegation()]]; } } elseif (is_string($assertion->var_id)) { $is_function = substr($assertion->var_id, -2) === '()'; @@ -1188,7 +1192,7 @@ protected static function processCustomAssertion( } } - $rule = clone $assertion->rule[0]->getNegation(); + $rule = $assertion->rule[0]->getNegation(); $assertion_var_id = str_replace($var_id, $arg_var_id, $assertion->var_id); @@ -1198,7 +1202,7 @@ protected static function processCustomAssertion( if (strpos($var_id, 'self::') === 0) { $var_id = $this_class_name.'::'.substr($var_id, 6); } - $if_types[$var_id] = [[clone $assertion->rule[0]->getNegation()]]; + $if_types[$var_id] = [[$assertion->rule[0]->getNegation()]]; } else { IssueBuffer::maybeAdd( new InvalidDocblock( @@ -1243,10 +1247,10 @@ protected static function getInstanceOfAssertions( if ($this_class_name && (in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], true))) { - $named_object =new TNamedObject($this_class_name); + $is_static = $stmt->class->parts[0] === 'static'; + $named_object = new TNamedObject($this_class_name, $is_static); - if ($stmt->class->parts[0] === 'static') { - $named_object->is_static = true; + if ($is_static) { return [new IsIdentical($named_object)]; } @@ -3337,7 +3341,7 @@ private static function getGetclassEqualityAssertions( new IsIdentical(new TTemplateParam( $type_part->param_name, $type_part->as_type - ? new Union([clone $type_part->as_type]) + ? new Union([$type_part->as_type]) : Type::getObject(), $type_part->defining_class )) @@ -3525,8 +3529,7 @@ private static function getIsaAssertions( if ($class_node->parts === ['static']) { if ($this_class_name) { - $object = new TNamedObject($this_class_name); - $object->is_static = true; + $object = new TNamedObject($this_class_name, true); $if_types[$first_var_name] = [[new IsAClass($object, $third_arg_value === 'true')]]; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php index b39e5579ce5..8640158444e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php @@ -770,8 +770,7 @@ public static function applyAssertionsToContext( continue; } - $assertion_rule = clone $assertion_rule; - $assertion_rule->setAtomicType($atomic_type); + $assertion_rule = $assertion_rule->setAtomicType($atomic_type); $orred_rules[] = $assertion_rule; } } elseif (isset($context->vars_in_scope[$assertion_var_id])) { diff --git a/src/Psalm/Storage/Assertion.php b/src/Psalm/Storage/Assertion.php index ed7dca2542d..2fcc4324bbc 100644 --- a/src/Psalm/Storage/Assertion.php +++ b/src/Psalm/Storage/Assertion.php @@ -4,12 +4,15 @@ use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ abstract class Assertion { - /** @psalm-mutation-free */ + use ImmutableNonCloneableTrait; + abstract public function getNegation(): Assertion; - /** @psalm-mutation-free */ abstract public function isNegationOf(self $assertion): bool; abstract public function __toString(): string; @@ -19,19 +22,21 @@ public function isNegation(): bool return false; } - /** @psalm-mutation-free */ public function hasEquality(): bool { return false; } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return null; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { + return $this; } } diff --git a/src/Psalm/Storage/Assertion/Any.php b/src/Psalm/Storage/Assertion/Any.php index 4aab3fda16a..c5d61036253 100644 --- a/src/Psalm/Storage/Assertion/Any.php +++ b/src/Psalm/Storage/Assertion/Any.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class Any extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return $this; @@ -17,7 +19,6 @@ public function __toString(): string return 'mixed'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php b/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php index 43a6f0bd557..e8fc33cb2ed 100644 --- a/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php +++ b/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class ArrayKeyDoesNotExist extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new ArrayKeyExists(); @@ -22,7 +24,6 @@ public function __toString(): string return '!array-key-exists'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof ArrayKeyExists; diff --git a/src/Psalm/Storage/Assertion/ArrayKeyExists.php b/src/Psalm/Storage/Assertion/ArrayKeyExists.php index 0b803cd4dd9..6ef5e84e244 100644 --- a/src/Psalm/Storage/Assertion/ArrayKeyExists.php +++ b/src/Psalm/Storage/Assertion/ArrayKeyExists.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class ArrayKeyExists extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new ArrayKeyDoesNotExist(); @@ -17,7 +19,6 @@ public function __toString(): string return 'array-key-exists'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof ArrayKeyDoesNotExist; diff --git a/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php b/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php index 297e61ddb83..7913cf60164 100644 --- a/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php +++ b/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class DoesNotHaveAtLeastCount extends Assertion { /** @var positive-int */ @@ -15,13 +18,11 @@ public function __construct(int $count) $this->count = $count; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new HasAtLeastCount($this->count); } - /** @psalm-mutation-free */ public function isNegation(): bool { return true; @@ -32,7 +33,6 @@ public function __toString(): string return '!has-at-least-' . $this->count; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof HasAtLeastCount && $this->count === $assertion->count; diff --git a/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php b/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php index 950bf72eba6..349e1533de4 100644 --- a/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php +++ b/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class DoesNotHaveExactCount extends Assertion { /** @var positive-int */ @@ -20,7 +23,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new HasExactCount($this->count); @@ -31,7 +33,6 @@ public function __toString(): string return '!has-exact-count-' . $this->count; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof HasExactCount && $assertion->count === $this->count; diff --git a/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php b/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php index eef48187543..64dc6fb4c95 100644 --- a/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php +++ b/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class DoesNotHaveMethod extends Assertion { public string $method; @@ -18,7 +21,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new HasMethod($this->method); @@ -29,7 +31,6 @@ public function __toString(): string return '!method-exists-' . $this->method; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof HasMethod && $assertion->method === $this->method; diff --git a/src/Psalm/Storage/Assertion/Empty_.php b/src/Psalm/Storage/Assertion/Empty_.php index 91613b0f4a2..f7e14b675b7 100644 --- a/src/Psalm/Storage/Assertion/Empty_.php +++ b/src/Psalm/Storage/Assertion/Empty_.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class Empty_ extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new NonEmpty(); @@ -22,7 +24,6 @@ public function __toString(): string return '!non-empty'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof NonEmpty; diff --git a/src/Psalm/Storage/Assertion/Falsy.php b/src/Psalm/Storage/Assertion/Falsy.php index 13c85088eeb..e555c2d16ea 100644 --- a/src/Psalm/Storage/Assertion/Falsy.php +++ b/src/Psalm/Storage/Assertion/Falsy.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class Falsy extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new Truthy(); @@ -22,7 +24,6 @@ public function __toString(): string return 'falsy'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof Truthy; diff --git a/src/Psalm/Storage/Assertion/HasArrayKey.php b/src/Psalm/Storage/Assertion/HasArrayKey.php index 7442c4a39a7..713eda3fe1e 100644 --- a/src/Psalm/Storage/Assertion/HasArrayKey.php +++ b/src/Psalm/Storage/Assertion/HasArrayKey.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use UnexpectedValueException; +/** + * @psalm-immutable + */ final class HasArrayKey extends Assertion { public $key; @@ -14,7 +17,6 @@ public function __construct(string $key) $this->key = $key; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { throw new UnexpectedValueException('This should never be called'); @@ -25,7 +27,6 @@ public function __toString(): string return 'has-array-key-' . $this->key; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/HasAtLeastCount.php b/src/Psalm/Storage/Assertion/HasAtLeastCount.php index 46ec83abfeb..3a30e1d5666 100644 --- a/src/Psalm/Storage/Assertion/HasAtLeastCount.php +++ b/src/Psalm/Storage/Assertion/HasAtLeastCount.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class HasAtLeastCount extends Assertion { /** @var positive-int */ @@ -15,7 +18,6 @@ public function __construct(int $count) $this->count = $count; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new DoesNotHaveAtLeastCount($this->count); @@ -26,7 +28,6 @@ public function __toString(): string return 'has-at-least-' . $this->count; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof DoesNotHaveAtLeastCount && $this->count === $assertion->count; diff --git a/src/Psalm/Storage/Assertion/HasExactCount.php b/src/Psalm/Storage/Assertion/HasExactCount.php index 36d0400c29c..b76cfc6144e 100644 --- a/src/Psalm/Storage/Assertion/HasExactCount.php +++ b/src/Psalm/Storage/Assertion/HasExactCount.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class HasExactCount extends Assertion { /** @var positive-int */ @@ -15,13 +18,11 @@ public function __construct(int $count) $this->count = $count; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new DoesNotHaveExactCount($this->count); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; @@ -32,7 +33,6 @@ public function __toString(): string return '=has-exact-count-' . $this->count; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof DoesNotHaveExactCount && $this->count === $assertion->count; diff --git a/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php b/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php index 88620c8b0f8..4bcafad2312 100644 --- a/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php +++ b/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php @@ -5,9 +5,11 @@ use Psalm\Storage\Assertion; use UnexpectedValueException; +/** + * @psalm-immutable + */ final class HasIntOrStringArrayAccess extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { throw new UnexpectedValueException('This should never be called'); @@ -18,7 +20,6 @@ public function __toString(): string return 'has-string-or-int-array-access'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/HasMethod.php b/src/Psalm/Storage/Assertion/HasMethod.php index 94508472404..2aef8f39814 100644 --- a/src/Psalm/Storage/Assertion/HasMethod.php +++ b/src/Psalm/Storage/Assertion/HasMethod.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class HasMethod extends Assertion { public string $method; @@ -13,7 +16,6 @@ public function __construct(string $method) $this->method = $method; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new DoesNotHaveMethod($this->method); @@ -24,7 +26,6 @@ public function __toString(): string return 'method-exists-' . $this->method; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof DoesNotHaveMethod && $this->method === $assertion->method; diff --git a/src/Psalm/Storage/Assertion/HasStringArrayAccess.php b/src/Psalm/Storage/Assertion/HasStringArrayAccess.php index d7595287857..d4aeb63c6e8 100644 --- a/src/Psalm/Storage/Assertion/HasStringArrayAccess.php +++ b/src/Psalm/Storage/Assertion/HasStringArrayAccess.php @@ -5,9 +5,11 @@ use Psalm\Storage\Assertion; use UnexpectedValueException; +/** + * @psalm-immutable + */ final class HasStringArrayAccess extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { throw new UnexpectedValueException('This should never be called'); @@ -18,7 +20,6 @@ public function __toString(): string return 'has-string-array-access'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/InArray.php b/src/Psalm/Storage/Assertion/InArray.php index b5e1abc2ea7..ac7220da007 100644 --- a/src/Psalm/Storage/Assertion/InArray.php +++ b/src/Psalm/Storage/Assertion/InArray.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Union; +/** + * @psalm-immutable + */ final class InArray extends Assertion { public Union $type; @@ -14,7 +17,6 @@ public function __construct(Union $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new NotInArray($this->type); @@ -25,7 +27,6 @@ public function __toString(): string return 'in-array-' . $this->type->getId(); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof NotInArray && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsAClass.php b/src/Psalm/Storage/Assertion/IsAClass.php index 3b6c5473952..ca5409e9268 100644 --- a/src/Psalm/Storage/Assertion/IsAClass.php +++ b/src/Psalm/Storage/Assertion/IsAClass.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsAClass extends Assertion { /** @var Atomic\TTemplateParamClass|Atomic\TNamedObject */ @@ -18,13 +21,11 @@ public function __construct(Atomic $type, bool $allow_string) $this->allow_string = $allow_string; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotAClass($this->type, $this->allow_string); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; @@ -35,7 +36,6 @@ public function __toString(): string return 'isa-' . ($this->allow_string ? 'string-' : '') . $this->type; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotAClass diff --git a/src/Psalm/Storage/Assertion/IsClassEqual.php b/src/Psalm/Storage/Assertion/IsClassEqual.php index da5307aa7f5..a7c92f2aab2 100644 --- a/src/Psalm/Storage/Assertion/IsClassEqual.php +++ b/src/Psalm/Storage/Assertion/IsClassEqual.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsClassEqual extends Assertion { public string $type; @@ -13,13 +16,11 @@ public function __construct(string $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsClassNotEqual($this->type); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; @@ -30,7 +31,6 @@ public function __toString(): string return '=get-class-' . $this->type; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsClassNotEqual && $this->type === $assertion->type; diff --git a/src/Psalm/Storage/Assertion/IsClassNotEqual.php b/src/Psalm/Storage/Assertion/IsClassNotEqual.php index c8d05dc8b77..ae4ed1329c7 100644 --- a/src/Psalm/Storage/Assertion/IsClassNotEqual.php +++ b/src/Psalm/Storage/Assertion/IsClassNotEqual.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsClassNotEqual extends Assertion { public string $type; @@ -18,7 +21,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsClassEqual($this->type); @@ -29,7 +31,6 @@ public function __toString(): string return '!=get-class-' . $this->type; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsClassEqual && $this->type === $assertion->type; diff --git a/src/Psalm/Storage/Assertion/IsCountable.php b/src/Psalm/Storage/Assertion/IsCountable.php index dea9295b28c..3933c4a13dd 100644 --- a/src/Psalm/Storage/Assertion/IsCountable.php +++ b/src/Psalm/Storage/Assertion/IsCountable.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsCountable extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotCountable(true); @@ -17,7 +19,6 @@ public function __toString(): string return 'countable'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotCountable && $assertion->is_negatable; diff --git a/src/Psalm/Storage/Assertion/IsEqualIsset.php b/src/Psalm/Storage/Assertion/IsEqualIsset.php index bded7c5ce06..8f754b375cf 100644 --- a/src/Psalm/Storage/Assertion/IsEqualIsset.php +++ b/src/Psalm/Storage/Assertion/IsEqualIsset.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsEqualIsset extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new Any(); @@ -17,13 +19,11 @@ public function __toString(): string return '=isset'; } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/IsGreaterThan.php b/src/Psalm/Storage/Assertion/IsGreaterThan.php index 131c3fc94a9..ed58ecabc99 100644 --- a/src/Psalm/Storage/Assertion/IsGreaterThan.php +++ b/src/Psalm/Storage/Assertion/IsGreaterThan.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsGreaterThan extends Assertion { public int $value; @@ -13,7 +16,6 @@ public function __construct(int $value) $this->value = $value; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsLessThanOrEqualTo($this->value); @@ -24,7 +26,6 @@ public function __toString(): string return '>' . $this->value; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsLessThanOrEqualTo && $this->value === $assertion->value; diff --git a/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php b/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php index ce8590eafc8..20a3c05d189 100644 --- a/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php +++ b/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsGreaterThanOrEqualTo extends Assertion { public int $value; @@ -18,7 +21,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsLessThan($this->value); @@ -29,7 +31,6 @@ public function __toString(): string return '!<' . $this->value; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsLessThan && $this->value === $assertion->value; diff --git a/src/Psalm/Storage/Assertion/IsIdentical.php b/src/Psalm/Storage/Assertion/IsIdentical.php index 9f6dccfae10..8730bda852d 100644 --- a/src/Psalm/Storage/Assertion/IsIdentical.php +++ b/src/Psalm/Storage/Assertion/IsIdentical.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsIdentical extends Assertion { public Atomic $type; @@ -14,7 +17,6 @@ public function __construct(Atomic $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotIdentical($this->type); @@ -25,24 +27,24 @@ public function __toString(): string return '=' . $this->type->getAssertionString(); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotIdentical && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsIsset.php b/src/Psalm/Storage/Assertion/IsIsset.php index 7b5fd06423b..219649181a1 100644 --- a/src/Psalm/Storage/Assertion/IsIsset.php +++ b/src/Psalm/Storage/Assertion/IsIsset.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsIsset extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotIsset(); @@ -17,7 +19,6 @@ public function __toString(): string return 'isset'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotIsset; diff --git a/src/Psalm/Storage/Assertion/IsLessThan.php b/src/Psalm/Storage/Assertion/IsLessThan.php index 0f26f5c53e1..8d78d4d4669 100644 --- a/src/Psalm/Storage/Assertion/IsLessThan.php +++ b/src/Psalm/Storage/Assertion/IsLessThan.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsLessThan extends Assertion { public int $value; @@ -13,7 +16,6 @@ public function __construct(int $value) $this->value = $value; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsGreaterThanOrEqualTo($this->value); @@ -24,7 +26,6 @@ public function __toString(): string return '<' . $this->value; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsGreaterThanOrEqualTo && $this->value === $assertion->value; diff --git a/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php b/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php index 36afbe8e282..2dd565915a1 100644 --- a/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php +++ b/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsLessThanOrEqualTo extends Assertion { public int $value; @@ -13,7 +16,6 @@ public function __construct(int $value) $this->value = $value; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsGreaterThan($this->value); @@ -29,7 +31,6 @@ public function __toString(): string return '!>' . $this->value; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsGreaterThan && $this->value === $assertion->value; diff --git a/src/Psalm/Storage/Assertion/IsLooselyEqual.php b/src/Psalm/Storage/Assertion/IsLooselyEqual.php index 35b1e6d6259..c0b23dbde7c 100644 --- a/src/Psalm/Storage/Assertion/IsLooselyEqual.php +++ b/src/Psalm/Storage/Assertion/IsLooselyEqual.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsLooselyEqual extends Assertion { public Atomic $type; @@ -14,7 +17,6 @@ public function __construct(Atomic $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotLooselyEqual($this->type); @@ -25,24 +27,24 @@ public function __toString(): string return '~' . $this->type->getAssertionString(); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotLooselyEqual && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsNotAClass.php b/src/Psalm/Storage/Assertion/IsNotAClass.php index 45cbd3442ef..7c542e1684c 100644 --- a/src/Psalm/Storage/Assertion/IsNotAClass.php +++ b/src/Psalm/Storage/Assertion/IsNotAClass.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsNotAClass extends Assertion { /** @var Atomic\TTemplateParamClass|Atomic\TNamedObject */ @@ -23,7 +26,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsAClass($this->type, $this->allow_string); @@ -34,7 +36,6 @@ public function __toString(): string return 'isa-' . ($this->allow_string ? 'string-' : '') . $this->type; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsAClass diff --git a/src/Psalm/Storage/Assertion/IsNotCountable.php b/src/Psalm/Storage/Assertion/IsNotCountable.php index b09a7a7dcdc..c76fe24e26e 100644 --- a/src/Psalm/Storage/Assertion/IsNotCountable.php +++ b/src/Psalm/Storage/Assertion/IsNotCountable.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsNotCountable extends Assertion { public $is_negatable; @@ -18,7 +21,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsCountable(); @@ -29,7 +31,6 @@ public function __toString(): string return '!countable'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsCountable; diff --git a/src/Psalm/Storage/Assertion/IsNotIdentical.php b/src/Psalm/Storage/Assertion/IsNotIdentical.php index 2c023300a02..978ca956df6 100644 --- a/src/Psalm/Storage/Assertion/IsNotIdentical.php +++ b/src/Psalm/Storage/Assertion/IsNotIdentical.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsNotIdentical extends Assertion { public Atomic $type; @@ -19,13 +22,11 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsIdentical($this->type); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; @@ -36,18 +37,19 @@ public function __toString(): string return '!=' . $this->type->getAssertionString(); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsIdentical && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsNotIsset.php b/src/Psalm/Storage/Assertion/IsNotIsset.php index defa8479a32..d42486326e6 100644 --- a/src/Psalm/Storage/Assertion/IsNotIsset.php +++ b/src/Psalm/Storage/Assertion/IsNotIsset.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class IsNotIsset extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsIsset(); @@ -22,7 +24,6 @@ public function __toString(): string return '!isset'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotIsset; diff --git a/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php b/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php index bcf77c78514..846afb19075 100644 --- a/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php +++ b/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsNotLooselyEqual extends Assertion { public Atomic $type; @@ -19,13 +22,11 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsLooselyEqual($this->type); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return true; @@ -36,18 +37,19 @@ public function __toString(): string return '!~' . $this->type->getAssertionString(); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsLooselyEqual && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsNotType.php b/src/Psalm/Storage/Assertion/IsNotType.php index 321dd744e0c..24d1ee9c380 100644 --- a/src/Psalm/Storage/Assertion/IsNotType.php +++ b/src/Psalm/Storage/Assertion/IsNotType.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsNotType extends Assertion { public Atomic $type; @@ -19,7 +22,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsType($this->type); @@ -30,18 +32,19 @@ public function __toString(): string return '!' . $this->type->getId(); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsType && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/IsType.php b/src/Psalm/Storage/Assertion/IsType.php index 2c822a79d40..501a5e06cca 100644 --- a/src/Psalm/Storage/Assertion/IsType.php +++ b/src/Psalm/Storage/Assertion/IsType.php @@ -5,6 +5,9 @@ use Psalm\Storage\Assertion; use Psalm\Type\Atomic; +/** + * @psalm-immutable + */ final class IsType extends Assertion { public Atomic $type; @@ -14,7 +17,6 @@ public function __construct(Atomic $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new IsNotType($this->type); @@ -25,18 +27,19 @@ public function __toString(): string return $this->type->getId(); } - /** @psalm-mutation-free */ public function getAtomicType(): ?Atomic { return $this->type; } - public function setAtomicType(Atomic $type): void + /** + * @return static + */ + public function setAtomicType(Atomic $type): self { - $this->type = $type; + return new static($type); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof IsNotType && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/NestedAssertions.php b/src/Psalm/Storage/Assertion/NestedAssertions.php index c7fa0a48e62..20f56ba585f 100644 --- a/src/Psalm/Storage/Assertion/NestedAssertions.php +++ b/src/Psalm/Storage/Assertion/NestedAssertions.php @@ -8,6 +8,9 @@ use const JSON_THROW_ON_ERROR; +/** + * @psalm-immutable + */ final class NestedAssertions extends Assertion { /** @var array>> */ @@ -19,7 +22,6 @@ public function __construct(array $assertions) $this->assertions = $assertions; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new NotNestedAssertions($this->assertions); @@ -30,7 +32,6 @@ public function __toString(): string return '@' . json_encode($this->assertions, JSON_THROW_ON_ERROR); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/NonEmpty.php b/src/Psalm/Storage/Assertion/NonEmpty.php index bb662d9591f..b45076d90c6 100644 --- a/src/Psalm/Storage/Assertion/NonEmpty.php +++ b/src/Psalm/Storage/Assertion/NonEmpty.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class NonEmpty extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new Empty_(); @@ -17,7 +19,6 @@ public function __toString(): string return 'non-empty'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof Empty_; diff --git a/src/Psalm/Storage/Assertion/NonEmptyCountable.php b/src/Psalm/Storage/Assertion/NonEmptyCountable.php index c42eca24d57..8c191d22c0a 100644 --- a/src/Psalm/Storage/Assertion/NonEmptyCountable.php +++ b/src/Psalm/Storage/Assertion/NonEmptyCountable.php @@ -4,6 +4,9 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class NonEmptyCountable extends Assertion { public $is_negatable; @@ -13,13 +16,11 @@ public function __construct(bool $is_negatable) $this->is_negatable = $is_negatable; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return $this->is_negatable ? new NotNonEmptyCountable() : new Any(); } - /** @psalm-mutation-free */ public function hasEquality(): bool { return !$this->is_negatable; @@ -30,7 +31,6 @@ public function __toString(): string return ($this->is_negatable ? '' : '=') . 'non-empty-countable'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $this->is_negatable && $assertion instanceof NotNonEmptyCountable; diff --git a/src/Psalm/Storage/Assertion/NotInArray.php b/src/Psalm/Storage/Assertion/NotInArray.php index 2dbbb71161b..73c352d47dd 100644 --- a/src/Psalm/Storage/Assertion/NotInArray.php +++ b/src/Psalm/Storage/Assertion/NotInArray.php @@ -5,8 +5,14 @@ use Psalm\Storage\Assertion; use Psalm\Type\Union; +/** + * @psalm-immutable + */ final class NotInArray extends Assertion { + /** + * @readonly + */ public Union $type; public function __construct(Union $type) @@ -14,7 +20,6 @@ public function __construct(Union $type) $this->type = $type; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new InArray($this->type); @@ -30,7 +35,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof InArray && $this->type->getId() === $assertion->type->getId(); diff --git a/src/Psalm/Storage/Assertion/NotNestedAssertions.php b/src/Psalm/Storage/Assertion/NotNestedAssertions.php index ad6f46f9ef6..7f2d33564c3 100644 --- a/src/Psalm/Storage/Assertion/NotNestedAssertions.php +++ b/src/Psalm/Storage/Assertion/NotNestedAssertions.php @@ -8,6 +8,9 @@ use const JSON_THROW_ON_ERROR; +/** + * @psalm-immutable + */ final class NotNestedAssertions extends Assertion { /** @var array>> */ @@ -24,7 +27,6 @@ public function isNegation(): bool return true; } - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new NestedAssertions($this->assertions); @@ -35,7 +37,6 @@ public function __toString(): string return '!@' . json_encode($this->assertions, JSON_THROW_ON_ERROR); } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return false; diff --git a/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php b/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php index d4a59fbd1a6..48fc743c373 100644 --- a/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php +++ b/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class NotNonEmptyCountable extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new NonEmptyCountable(true); @@ -22,7 +24,6 @@ public function __toString(): string return '!non-empty-countable'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof NonEmptyCountable && $assertion->is_negatable; diff --git a/src/Psalm/Storage/Assertion/Truthy.php b/src/Psalm/Storage/Assertion/Truthy.php index 1d92be6e158..ef853b0b3b3 100644 --- a/src/Psalm/Storage/Assertion/Truthy.php +++ b/src/Psalm/Storage/Assertion/Truthy.php @@ -4,9 +4,11 @@ use Psalm\Storage\Assertion; +/** + * @psalm-immutable + */ final class Truthy extends Assertion { - /** @psalm-mutation-free */ public function getNegation(): Assertion { return new Falsy(); @@ -17,7 +19,6 @@ public function __toString(): string return '!falsy'; } - /** @psalm-mutation-free */ public function isNegationOf(Assertion $assertion): bool { return $assertion instanceof Falsy; diff --git a/src/Psalm/Storage/ImmutableNonCloneableTrait.php b/src/Psalm/Storage/ImmutableNonCloneableTrait.php new file mode 100644 index 00000000000..7609a73a8a4 --- /dev/null +++ b/src/Psalm/Storage/ImmutableNonCloneableTrait.php @@ -0,0 +1,13 @@ +getAtomicTypes() as $atomic_type) { - $assertion = clone $assertion; - $assertion->setAtomicType($atomic_type); + $assertion = $assertion->setAtomicType($atomic_type); $assertion_rules[] = $assertion; } } else { diff --git a/tests/AlgebraTest.php b/tests/AlgebraTest.php index 6571701c436..a4b7eb8085e 100644 --- a/tests/AlgebraTest.php +++ b/tests/AlgebraTest.php @@ -83,7 +83,7 @@ public function testNegateFormulaWithUnreconcilableTerm(): void $a1 = new IsType(new TInt()); $formula = [ new Clause(['$a' => [(string)$a1 => $a1]], 1, 1), - new Clause(['$b' => [(string)$a1 => clone $a1]], 1, 2, false, false), + new Clause(['$b' => [(string)$a1 => $a1]], 1, 2, false, false), ]; $negated_formula = Algebra::negateFormula($formula);