addStubFile( 'stubOne.phpstub', 'addFile( 'somefile.php', 'analyzeFile('somefile.php', new Context()); } public function providerValidCodeParse(): iterable { return [ 'classAndPropertyAttributesExists' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => 'getAttributes(BaseAttribute::class, 2) as $attr) { $attribute = $attr->newInstance(); echo $attribute->name; } }', 'assertions' => [], 'ignored_issues' => [], 'php_version' => '8.0' ], 'testReflectingAllAttributes' => [ 'code' => 'getAttributes(); ', 'assertions' => [ '$b' => 'list>', ], 'ignored_issues' => [], 'php_version' => '8.0' ], 'convertKeyedArray' => [ 'code' => 'methods = $methods; } } #[Route(methods: ["GET"])] class HealthController {}', ], 'allowsRepeatableFlag' => [ 'code' => ' [ 'code' => ' $_className */ public function __construct(string $_className) { } } #[Foo(_className: Baz::class)] class Baz {}', ], 'allowsClassStringFromDifferentNamespace' => [ 'code' => ' $className */ public function __construct(string $className) { $this->className = $className; } } interface FoobarInterface {} class Bar implements FoobarInterface {} } namespace NamespaceTwo { use NamespaceOne\FooAttribute; use NamespaceOne\Bar as ZZ; #[FooAttribute(className: ZZ::class)] class Baz {} } ' ], 'returnTypeWillChange7.1' => [ 'code' => ' [], 'ignored_issues' => [], 'php_version' => '7.1' ], 'returnTypeWillChange8.1' => [ 'code' => ' [], 'ignored_issues' => [], 'php_version' => '8.1' ], 'allowDynamicProperties' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:4:23', ], 'missingAttributeOnClass' => [ 'code' => ' 'UndefinedAttributeClass - src' . DIRECTORY_SEPARATOR . 'somefile.php:4:23', ], 'missingAttributeOnProperty' => [ 'code' => ' 'UndefinedAttributeClass - src' . DIRECTORY_SEPARATOR . 'somefile.php:6:27', ], 'missingAttributeOnFunction' => [ 'code' => ' 'UndefinedAttributeClass - src' . DIRECTORY_SEPARATOR . 'somefile.php:4:23', ], 'missingAttributeOnParam' => [ 'code' => ' 'UndefinedAttributeClass - src' . DIRECTORY_SEPARATOR . 'somefile.php:4:36', ], 'tooFewArgumentsToAttributeConstructor' => [ 'code' => ' 'TooFewArguments - src' . DIRECTORY_SEPARATOR . 'somefile.php:9:23', ], 'invalidArgument' => [ 'code' => ' 'InvalidScalarArgument - src' . DIRECTORY_SEPARATOR . 'somefile.php:10:27', ], 'classAttributeUsedOnFunction' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:9:23', ], 'interfaceCannotBeAttributeClass' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:2:23', ], 'traitCannotBeAttributeClass' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:2:23', ], 'abstractClassCannotBeAttributeClass' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:2:23', ], 'attributeClassCannotHavePrivateConstructor' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:2:23', ], 'SKIPPED-attributeInvalidTargetClassConst' => [ // Will be implemented in Psalm 5 where we have better class const analysis 'code' => ' 'InvalidAttribute', ], 'attributeInvalidTargetProperty' => [ 'code' => ' 'InvalidAttribute', ], 'attributeInvalidTargetMethod' => [ 'code' => ' 'InvalidAttribute', ], 'attributeInvalidTargetFunction' => [ 'code' => ' 'InvalidAttribute', ], 'attributeInvalidTargetParameter' => [ 'code' => ' 'InvalidAttribute', ], 'attributeTargetArgCannotBeVariable' => [ 'code' => ' 'UndefinedVariable', ], 'attributeTargetArgCannotBeSelfConst' => [ 'code' => ' 'NonStaticSelfCall', ], 'noParentInAttributeOnClassWithoutParent' => [ 'code' => ' 'ParentNotFound', ], 'undefinedConstantInAttribute' => [ 'code' => ' 'UndefinedConstant', ], 'getAttributesOnClassWithNonClassAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:8:39 - Attribute Attr cannot be used on a class', ], 'getAttributesOnFunctionWithNonFunctionAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:9:39 - Attribute Attr cannot be used on a function', ], 'getAttributesOnMethodWithNonMethodAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:11:39 - Attribute Attr cannot be used on a method', ], 'getAttributesOnPropertyWithNonPropertyAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:11:39 - Attribute Attr cannot be used on a property', ], 'getAttributesOnClassConstantWithNonClassConstantAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:11:39 - Attribute Attr cannot be used on a class constant', ], 'getAttributesOnParameterWithNonParameterAttribute' => [ 'code' => 'getAttributes(Attr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:8:39 - Attribute Attr cannot be used on a function/method parameter', ], 'getAttributesWithNonAttribute' => [ 'code' => 'getAttributes(NonAttr::class); ', 'error_message' => 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:7:39 - The class NonAttr doesn\'t have the Attribute attribute', ], 'analyzeConstructorForNonexistentAttributes' => [ 'code' => ' 'InvalidScalarArgument', ], 'multipleAttributesShowErrors' => [ 'code' => ' 'InvalidAttribute', ], 'repeatNonRepeatableAttribute' => [ 'code' => ' 'InvalidAttribute - src' . DIRECTORY_SEPARATOR . 'somefile.php:5:28 - Attribute Foo is not repeatable', ], 'invalidAttributeConstructionWithReturningFunction' => [ 'code' => ' 'UndefinedConstant', 'ignored_issues' => [], 'php_version' => '8.1', ], 'sensitiveParameterOnMethod' => [ 'code' => ' 'Attribute SensitiveParameter cannot be used on a method', ], ]; } }