,error_levels?:string[]}> */ public function providerValidCodeParse() { return [ 'extendsAndImplements' => [ 'baz(); $dee = (new D())->fooFoo();', 'assertions' => [ '$cee' => 'string', '$dee' => 'string', ], ], 'isExtendedInterface' => [ ' [ ' [ 'fooFoo(); }', ], 'correctInterfaceMethodSignature' => [ ' [ ' [ ' [ ' [ 'foo(); } }', ], 'abstractInterfaceImplements' => [ ' [ 'foo(); } }', ], 'implementsPartialInterfaceMethods' => [ ' [], 'error_levels' => ['MissingReturnType'], ], 'interfaceConstants' => [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ 'blah();', ], 'interfaceExtendsTraversible' => [ ' [ ' [ ' [ ' $a * @param array $b */ function g(array $a, array $b): bool { return $a === $b; } $o = new C; f($o, $o);', ], 'interfacePropertyIntersection' => [ 'a; $i->a = "hello"; } }', ], 'interfacePropertyIntersectionMockPropertyAccess' => [ 'a; $i->a = "hello"; } }', ], 'interfacePropertyIntersectionMockMethodAccess' => [ 'foo(); } } function takeA(A $a) : void { if ($a instanceof I) { $a->foo(); } }', ], 'docblockParamInheritance' => [ 'f = $f; } } class C2 implements I { /** @var string[] */ private $f = []; /** * {@inheritDoc} */ public function foo(array $f) : void { $this->f = $f; } }', ], 'allowStaticCallOnInterfaceMethod' => [ ' [ 'current(); }', ], 'intersectMixedTypes' => [ 'foo(); } /** @param IBar&IFoo $i */ function iBarFirst($i) : string { return $i->foo(); }', ], 'intersectionObjectTypes' => [ 'foo(); } /** @param IBar&IFoo $i */ function iBarFirst($i) : C { return $i->foo(); }', ], 'noTypeCoercionWhenIntersectionMatches' => [ ' [ '&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' => [ ' [ 'm()->m(); } function f2(G $f) : void { $f->m()->m(); } function f3(H $f) : void { $f->m()->m(); }' ], ]; } /** * @return iterable */ public function providerInvalidCodeParse() { return [ 'invalidInterface' => [ ' 'UndefinedClass', ], 'noInterfacePropertyFetch' => [ 'bar) { } }', 'error_message' => 'NoInterfaceProperties', ], 'noInterfacePropertyAssignment' => [ 'bar = 5; }', 'error_message' => 'NoInterfaceProperties', ], 'unimplementedInterfaceMethod' => [ ' 'UnimplementedInterfaceMethod', ], 'mismatchingInterfaceMethodSignature' => [ ' 'MethodSignatureMismatch', ], 'mismatchingInterfaceMethodSignatureInTrait' => [ ' 'MethodSignatureMismatch', ], 'mismatchingInterfaceMethodSignatureInImplementer' => [ ' 'MethodSignatureMismatch', ], 'mismatchingReturnTypes' => [ ' 'MethodSignatureMismatch', ], 'mismatchingDocblockReturnTypes' => [ ' 'ImplementedReturnTypeMismatch', ], 'abstractInterfaceImplementsButCallUndefinedMethod' => [ 'foo2(); } }', 'error_message' => 'UndefinedMethod', ], 'abstractInterfaceImplementsWithSubclass' => [ ' 'UnimplementedInterfaceMethod', ], 'lessSpecificReturnStatement' => [ ' 'LessSpecificReturnStatement', ], 'interfaceInstanceofAndTwoReturns' => [ ' 'InvalidReturnStatement', ], 'deprecatedInterface' => [ ' 'DeprecatedInterface', ], 'inheritMultipleInterfacesWithConflictingDocblocks' => [ ' 'InvalidReturnType', ], 'interfaceInstantiation' => [ ' 'InterfaceInstantiation', ], 'nonStaticInterfaceMethod' => [ ' 'MethodSignatureMismatch', ], 'staticInterfaceCall' => [ ' 'UndefinedClass', ], 'missingReturnType' => [ ' 'MissingReturnType' ], 'missingParamType' => [ ' 'MissingParamType' ], ]; } }