Skip to content


All notable changes to this project will be documented in this file.


  • Fix template names getting resolved as FQCNs in throws docs.


  • Add shouldNotBeReadonly assertion.
  • Fix return types when building declaration rules with tips.


  • Add shouldInclude() and shouldNotInclude assertions.
  • Detect catch blocks in dependency assertions.
  • Fix shouldBeNamed assertion not functioning on second run.


  • Fix namespace selector matching similar namespaces.


  • Add shouldBeNamed() assertion.
  • Add shouldBeInterface() assertion.


  • Add #[TestRule] attribute to mark test's methods as rules.
  • Add shouldApplyAttribute() assertion.
  • Deprecate hasAttribute() selector in favor of appliesAttribute().
  • Allow extending test files.


  • Add shouldOnlyHaveOnePublicMethod() assertion.
  • Fix return type of target excludes builder step.


  • Add hasAttribute() selector.
  • Deprecate namespace() selector in favor of inNamespace().
  • Deprecate interface() selector in favor of isInterface().
  • Deprecate abstract() selector in favor of isAbstract().
  • Deprecate final() selector in favor of isFinal().
  • Deprecate readonly() selector in favor of isReadonly().
  • Deprecate enum() selector in favor of isEnum().
  • Deprecate attribute() selector in favor of isAttribute().


  • Fix Should- rules ignoring classes with empty findings.


  • Add tips to rule building using because().
  • Add readonly() selector and shouldBeReadonly() assertion.


  • Added parent and direct interfaces as dependencies.
  • Fixed Stringable not treated as built-in class.


  • Added Selector::AND() modifier.


  • Added ignore_built_in_classes option to ignore built-in classes on relation assertions.
  • Added show_rule_names option to output the rule name before the error message.
  • Added class Attributes as dependencies.
  • Fixed template names getting resolved as FQCNs.


  • Added canOnlyDepend() assertion.


  • Added shouldBeAbstract() and shouldNotBeAbstract() assertions.
  • Fixed shouldNotDependOn() assertion ignoring static method calls.


  • Added shouldBeFinal() and shouldNotBeFinal() assertions.

0.10.0 ⚠

  • Reconversion of the project as a PHPStan extension

Read the upgrade guide for more information.


  • Read configured tests.path recursively


  • Fix phar file generation
  • Make paths relative to configuration file


  • Update event-dispatcher to allow psr/container v2


  • Fix class property types not caught as dependencies
  • Support PHP 8.1 features:
  • Enums
  • never type
  • Intersection types


  • Add Symfony 6 compatibility


  • Fix exception when no files found in path selector
  • Improve RegexClassName match performance


  • Add PHP 8.0 and 8.1 compatibility
  • Drop PHP 7.2 and 7.3 compatibility
  • Support PHP 8.0 features:
  • Constructor promotion
  • Named Parameters
  • Union Types
  • Attributes
  • Match and Throw Expression
  • Rename ignore_docblocks to ignore-docblocks
  • Rename ignore_php_extensions to ignore-php-extensions
  • Remove dry-run option
  • Add php-version option to force emulative lexer php version
  • Move main executable file to /bin/phpat
  • Update min/max composer dependencies versions
  • Remove BetterReflection usage
  • Add default composer configuration
  • Accept snake_case test filenames
  • Baseline file
  • Fix wrongly mapped fully qualified classnames on docblocks
  • Ignore dependencies out of the class context
  • Remove regex selections with results from origins to avoid duplicated statements


  • Do not analyze excluded files (+info)


  • Move CI to GitHub Actions
  • Optimize FullClassName usage


  • Fix random silent failures while creating internal php classmap
  • Fix test file valid names
  • Set default verbosity on invalid configuration


  • Fix exclusions when they are not part of the src
  • Allow to include test files with more valid names


  • Change composer package name to phpat/phpat
  • Refactor AST build to a better-reflection/php-parse hybrid
  • Add support to generic types in docs
  • Add support to callable types in docs
  • Add support to union types in docs
  • Fix src path configuration sometimes giving issues
  • Drop Symfony 2 compatibility
  • Move Fatal Error exceptions out of event listener
  • Fix issue with FQCNs starting with backslash
  • Add psalm and phpstan to CI checks


  • Move composer parsing to ReferenceMap creation stage
  • Include unknown FQCNs (out of src) in ClassNameSelector


  • Fix composer dependencies with empty namespace selected as *


  • Package name changed to phpat/phpat
  • Add support for tests in YAML and XML files
  • Ignore only core and extension classes (instead of all classes without namespace)
  • Add ignore_php_extensions option
  • Change ignore_docblocks option name
  • Change the configuration needed for composer selectors:
    # phpat.yaml
        json: path-to-composer.json
        lock: path-to-composer.lock
  • Modify ComposerSourceSelector and ComposerDependencySelector so:
  • areAutoloadableFromComposer selects non-dev composer autoload classes
  • areDevAutoloadableFromComposer selects dev composer autoload classes
  • areDependenciesFromComposer selects non-dev composer dependencies
  • areDevDependenciesFromComposer selects dev composer dependencies


  • Fix exclusions ignored in non-ast classes
  • Add ComposerSourceSelector and ComposerDependencySelector
        ->classesThat(Selector::areAutoloadableFromComposer('file-composer-json', false))
        ->classesThat(Selector::areDependenciesFromComposer('file-composer-json', 'file-composer-lock', true))


  • Add selection out of the src scope using full or partial class names
  • Add warnings when using regex class names with affirmative must assertions
  • Fix some docblock types not resolved
  • Fix error while using anonymous classes


  • Add warnings when selectors do not find any class
  • Fix group use declarations
  • Fix some functions and primitive types resolved as classes
  • Ignore dependencies without namespace (predefined PHP classes)


  • Added support for * on include and exclude options
  • Fixed ignored include option when using other than PathSelector
  • Modified command now looks for default phpat.yaml or phpat.yml files
  • Modified success report character from · to .


  • Fixed false exception message shown on violated rules report


  • Added dry-run to internal errors
  • Modified fatal error handler
  • Modified executable to match php version requirement
  • Fixed include option


  • Added CanOnlyImplement and MustOnlyImplement rule types
  • Added CanOnlyInclude and MustOnlyInclude rule type
  • Added CanOnlyDepend and MustOnlyDepend rule types
  • Added CanOnlyExtend rule type
  • Modified statements now check all the defined relations of a class
  • Fixed native PHP classes not correctly found


  • Added Selector::implementInterface to select classes that implement a certain interface
  • Added Selector::extendClass to select classes that extend a certain class
  • Added Selector::includeTrait to select classes that include a certain trait
  • Added some PHP configurations (error_reporting, display_errors, gc_disable)
  • Added verbosity as a cli command option
  • Fixed options being ignored in configuration files


  • Added Selector::haveClassName to select classes by fully qualified names
  • Performance boost by building an AST map instead of parsing each time


  • Added a changelog :smile:
  • Changed Minimum PHP version from 7.1 to 7.2.
  • Changed dependency symfony/event-dispatcher to carlosas/simple-event-dispatcher.