[ 'code' => 'baz(); $dee = (new D())->fooFoo();', 'assertions' => [ '$cee' => 'string', '$dee' => 'string', ], ], 'isExtendedInterface' => [ 'code' => ' [ 'code' => ' [ 'code' => 'fooFoo(); }', ], 'correctInterfaceMethodSignature' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => 'foo(); } }', ], 'abstractInterfaceImplements' => [ 'code' => ' [ 'code' => 'foo(); } }', ], 'implementsPartialInterfaceMethods' => [ 'code' => ' [], 'ignored_issues' => ['MissingReturnType'], ], 'interfaceConstants' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => '> */ class SomeIterator extends IteratorIterator {}', ], 'SKIPPED-suppressMismatch' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => 'blah();', ], 'interfaceExtendsTraversible' => [ 'code' => ' * @extends ArrayAccess */ interface Collection extends Countable, IteratorAggregate, ArrayAccess {} function takesCollection(Collection $c): void { takesIterable($c); } function takesIterable(iterable $i): void {}', ], 'interfaceInstanceofInterfaceOrClass' => [ 'code' => ' [ 'code' => ' */ interface I2 extends Iterator {} /** * @extends FilterIterator> */ class DedupeIterator extends FilterIterator { public function __construct(I2 $i) { parent::__construct($i); } public function accept() : bool { return true; } }', ], 'interfacInstanceMayContainOtherInterfaceInstance' => [ 'code' => ' $a * @param array $b */ function g(array $a, array $b): bool { return $a === $b; } $o = new C; f($o, $o);', ], 'interfacePropertyIntersection' => [ 'code' => 'a; $i->a = "hello"; } }', ], 'interfacePropertyIntersectionMockPropertyAccess' => [ 'code' => 'a; $i->a = "hello"; } }', ], 'interfacePropertyIntersectionMockMethodAccess' => [ 'code' => 'foo(); } } function takeA(A $a) : void { if ($a instanceof I) { $a->foo(); } }', ], 'docblockParamInheritance' => [ 'code' => 'f = $f; } } class C2 implements I { /** @var string[] */ private $f = []; /** * {@inheritDoc} */ public function foo(array $f) : void { $this->f = $f; } }', ], 'allowStaticCallOnInterfaceMethod' => [ 'code' => ' [ 'code' => 'current(); }', ], 'intersectMixedTypes' => [ 'code' => 'foo(); } /** @param IBar&IFoo $i */ function iBarFirst($i) : string { return $i->foo(); }', ], 'intersectionObjectTypes' => [ 'code' => 'foo(); } /** @param IBar&IFoo $i */ function iBarFirst($i) : C { return $i->foo(); }', ], 'noTypeCoercionWhenIntersectionMatches' => [ 'code' => ' [ 'code' => '&iterable $i */ function takesIntersectionOfIterables(iterable $i): void { foreach ($i as $c) { takesA($c); takesB($c); } } /** @psalm-param iterable $i */ function takesIterableOfIntersections(iterable $i): void { foreach ($i as $c) { takesA($c); takesB($c); } }', ], 'inheritDocFromObviousInterface' => [ 'code' => ' [ 'code' => 'm()->m(); } function f2(G $f) : void { $f->m()->m(); } function f3(H $f) : void { $f->m()->m(); }', ], 'dontModifyAfterUnnecessaryAssertion' => [ 'code' => ' [ 'code' => 'doStuff(); } }', 'assertions' => [], 'ignored_issues' => [], 'php_version' => '8.0', ], ]; } public function providerInvalidCodeParse(): iterable { return [ 'invalidInterface' => [ 'code' => ' 'UndefinedClass', ], 'noInterfacePropertyFetch' => [ 'code' => 'bar) { } }', 'error_message' => 'NoInterfaceProperties', ], 'noInterfacePropertyAssignment' => [ 'code' => 'bar = 5; }', 'error_message' => 'NoInterfaceProperties', ], 'unimplementedInterfaceMethod' => [ 'code' => ' 'UnimplementedInterfaceMethod', ], 'mismatchingInterfaceMethodSignature' => [ 'code' => ' 'MethodSignatureMismatch', ], 'mismatchingInterfaceMethodSignatureInTrait' => [ 'code' => ' 'MethodSignatureMismatch', ], 'mismatchingInterfaceMethodSignatureInImplementer' => [ 'code' => ' 'MethodSignatureMismatch', ], 'mismatchingReturnTypes' => [ 'code' => ' 'MethodSignatureMismatch', ], 'mismatchingDocblockReturnTypes' => [ 'code' => ' 'ImplementedReturnTypeMismatch', ], 'abstractInterfaceImplementsButCallUndefinedMethod' => [ 'code' => 'foo2(); } }', 'error_message' => 'UndefinedMethod', ], 'abstractInterfaceImplementsWithSubclass' => [ 'code' => ' 'UnimplementedInterfaceMethod', ], 'lessSpecificReturnStatement' => [ 'code' => ' 'LessSpecificReturnStatement', ], 'interfaceInstanceofAndTwoReturns' => [ 'code' => ' 'InvalidReturnStatement', ], 'deprecatedInterface' => [ 'code' => ' 'DeprecatedInterface', ], 'inheritMultipleInterfacesWithConflictingDocblocks' => [ 'code' => ' 'InvalidReturnType', ], 'interfaceInstantiation' => [ 'code' => ' 'InterfaceInstantiation', ], 'nonStaticInterfaceMethod' => [ 'code' => ' 'MethodSignatureMismatch', ], 'staticInterfaceCall' => [ 'code' => ' 'UndefinedClass', ], 'missingReturnType' => [ 'code' => ' 'MissingReturnType', ], 'missingParamType' => [ 'code' => ' 'MissingParamType', ], 'missingTemplateExtendsInterface' => [ 'code' => ' 'MissingTemplateParam', ], 'missingTemplateExtendsNativeInterface' => [ 'code' => ' 'MissingTemplateParam', ], 'missingTemplateExtendsNativeMultipleInterface' => [ 'code' => ' */ interface a extends Iterator, Traversable { } ', 'error_message' => 'MissingTemplateParam', ], 'reconcileAfterClassInstanceof' => [ 'code' => 'bar(); } $foo->bar(); }', 'error_message' => 'UndefinedInterfaceMethod - src' . DIRECTORY_SEPARATOR . 'somefile.php:13:31', ], 'reconcileAfterInterfaceInstanceof' => [ 'code' => 'bar(); } $foo->bar(); }', 'error_message' => 'UndefinedInterfaceMethod - src' . DIRECTORY_SEPARATOR . 'somefile.php:13:31', ], ]; } }