[ 'code' => ' [ 'code' => ' [ 'code' => '$1", $output); return $output; }', ], 'implicitAnnotations' => [ 'code' => 'setOptions($options); $this->setDefaultOptions($this->getOptions()); } function getOptions(): array { return $this->options; } public final function setOptions(array $options): void { $this->options = $options; } public final function setDefaultOptions(array $defaultOptions): void { $this->defaultOptions = $defaultOptions; } }', ], 'canCreateObjectWithNoExternalMutations' => [ 'code' => 'count = $count; } public function increment() : void { $this->count++; } public function incrementByTwo() : void { $this->count = $this->count + 2; } public function incrementByFive() : void { $this->count += 5; } } /** @psalm-pure */ function makesACounter(int $i) : Counter { $c = new Counter($i); $c->increment(); $c->incrementByTwo(); $c->incrementByFive(); return $c; }', ], 'canCreateImmutableObject' => [ 'code' => 's = $s; } public function getShort() : string { return substr($this->s, 0, 5); } } /** @psalm-pure */ function makeA(string $s) : A { $a = new A($s); if ($a->getShort() === "bar") { return new A("foo"); } return $a; }', ], 'assertIsPureInProductionn' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' $b; }); return $ar[0] ?? 0; }', ], 'exitFunctionWithNoArgumentIsPure' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => 'getMessage(); } echo getMessage(new Exception("test"));', ], 'exceptionGetCode' => [ 'code' => 'getCode(); } echo getCode(new Exception("test"));', ], 'exceptionGetFile' => [ 'code' => 'getFile(); } echo getFile(new Exception("test"));', ], 'exceptionGetLine' => [ 'code' => 'getLine(); } echo getLine(new Exception("test"));', ], 'exceptionGetTrace' => [ 'code' => 'getTrace(); } echo count(getTrace(new Exception("test")));', ], 'exceptionGetPrevious' => [ 'code' => 'getPrevious(); } echo gettype(getPrevious(new Exception("test")));', ], 'exceptionGetTraceAsString' => [ 'code' => 'getTraceAsString(); } echo getTraceAsString(new Exception("test"));', ], 'callingMethodInThrowStillPure' => [ 'code' => ' 9000) { throw MyException::hello(); } if ($sum > 900) { throw new MyException(); } return $sum; }', ], 'countMethodCanBePure' => [ 'code' => ' [ 'code' => 'other = $other; } /** * @psalm-mutation-free * @psalm-assert !null $this->other */ public function checkNotNullNested(): bool { if ($this->other === null) { throw new RuntimeException("oops"); } return !!$this->other->other; } public function foo() : void {} public function doSomething(): void { $this->checkNotNullNested(); $this->other->foo(); } }', ], 'allowPropertyAccessOnImmutableClass' => [ 'code' => 'a = $a; } } /** @psalm-pure */ function filterOdd(A $a) : bool { if ($a->a % 2 === 0) { return true; } return false; }', ], 'allowPureInConstrucctorThis' => [ 'code' => 'isValidPort($portNumber)) { throw new Exception(); } $this->portNumber = $portNumber; } /** * @psalm-pure */ private function isValidPort(int $portNumber): bool { return $portNumber >= 1 && $portNumber <= 1000; } }', ], 'pureThroughCallStatic' => [ 'code' => ' [ 'code' => ' [ 'code' => 'a = $i; if ($i % 2 === 0 || $a->a === 2) { return $i; } return null; }', 'error_message' => 'ImpurePropertyAssignment', ], 'impureMethodCall' => [ 'code' => 'a++; } } /** @psalm-pure */ function filterOdd(int $i, A $a) : ?int { $a->foo(); if ($i % 2 === 0 || $a->a === 2) { return $i; } return null; }', 'error_message' => 'ImpureMethodCall', ], 'impureFunctionCall' => [ 'code' => ' 'ImpureFunctionCall', ], 'impureConstructorCall' => [ 'code' => 'a++; } } /** @psalm-pure */ function filterOdd(int $i, A $a) : ?int { $b = new B($a); if ($i % 2 === 0 || $a->a === 2) { return $i; } return null; }', 'error_message' => 'ImpureMethodCall', ], 'canCreateObjectWithNoExternalMutations' => [ 'code' => 'count = $count; } public function increment() : void { $this->count += rand(0, 5); } } /** @psalm-pure */ function makesACounter(int $i) : Counter { $c = new Counter($i); $c->increment(); return $c; }', 'error_message' => 'ImpureMethodCall', ], 'useOfStaticMakesFunctionImpure' => [ 'code' => ' 'ImpureStaticVariable', ], 'preventImpureArrayMapClosure' => [ 'code' => ' 'ImpureFunctionCall', ], 'sortFunctionImpure' => [ 'code' => ' $b; }); return $ar[0] ?? 0; }', 'error_message' => 'ImpureFunctionCall', ], 'printFunctionIsImpure' => [ 'code' => ' 'ImpureFunctionCall', ], 'exitFunctionWithNonIntegerArgumentIsImpure' => [ 'code' => ' 'ImpureFunctionCall', ], 'dieFunctionWithNonIntegerArgumentIsImpure' => [ 'code' => ' 'ImpureFunctionCall', ], 'impureByRef' => [ 'code' => ' 'ImpureByReferenceAssignment', ], 'staticPropertyFetch' => [ 'code' => ' 'ImpureStaticProperty', ], 'staticPropertyAssignment' => [ 'code' => ' 'ImpureStaticProperty', ], 'preventImpureToStringViaComparison' => [ 'code' => ' 'ImpureMethodCall', ], 'preventImpureToStringViaConcatenation' => [ 'code' => ' 'ImpureMethodCall', ], 'countCanBeImpure' => [ 'code' => ' 'ImpureFunctionCall', ], 'propertyFetchIsNotPure' => [ 'code' => 'foo; } }', 'error_message' => 'ImpurePropertyFetch', ], 'preventPropertyAccessOnMutableClass' => [ 'code' => 'a = $a; } } /** @psalm-pure */ function filterOdd(A $a) : bool { if ($a->a % 2 === 0) { return true; } return false; }', 'error_message' => 'ImpurePropertyFetch', ], 'preventIssetOnMutableClassKnownProperty' => [ 'code' => 'a = $a; } } /** @psalm-pure */ function filterOdd(A $a) : bool { if (isset($a->a)) { return true; } return false; }', 'error_message' => 'ImpurePropertyFetch', ], 'preventIssetOnMutableClassUnknownProperty' => [ 'code' => 'a = $a; } } /** @psalm-pure */ function filterOdd(A $a) : bool { if (isset($a->b)) { return true; } return false; }', 'error_message' => 'ImpurePropertyFetch', ], 'impureThis' => [ 'code' => ' 'ImpureVariable', ], 'iterableIsNotPure' => [ 'code' => ' $pieces * * @psalm-pure */ function foo(iterable $pieces): string { foreach ($pieces as $piece) { return $piece; } return "jello"; }', 'error_message' => 'ImpureMethodCall', ], 'impureThroughCallStatic' => [ 'code' => ' 'ImpureMethodCall', ], 'impureCallableInImmutableContext' => [ 'code' => 'fold( function (): void {} ); } } new Whatever(); ', 'error_message' => 'ImpureFunctionCall', ], ]; } }