vimeo/psalm
66.9
Adequate · 19 September 2026
2104.4k
lines of production code
PHP
primary language
1
measurement over time
What this system is
This system is Psalm, a static analysis tool for PHP code that performs deep type checking, taint analysis, and code refactoring. It operates by parsing PHP source code into an abstract syntax tree, resolving types against comprehensive internal and external stubs, and applying specialized analyzers to detect errors, security vulnerabilities, and logical inconsistencies. The tool supports integration with development workflows through a Language Server Protocol interface, parallel processing for performance, and a plugin architecture for extensible, custom analysis rules.
How it got here
2016–2018 — Architectural refactoring and type system overhaul
42 changes.
This period focused on a comprehensive restructuring of Psalm's internal architecture, breaking down monolithic analyzers into specialized, single-responsibility classes for statements, expressions, and control flow. The type system was significantly enhanced by introducing immutable Union and Atomic type classes, while the Language Server and plugin infrastructure were modernized with dedicated handlers and a new registration model.
2019–2020 — AST analysis modularization and reporting expansion
38 changes.
This period focused on refactoring Psalm's internal architecture by breaking down monolithic analyzers and visitors into specialized, modular classes for AST traversal, type comparison, and method analysis. It also introduced comprehensive new reporting formats, improved return type inference for array functions, and added robust support for CI metadata and taint tracking.
2021–2026 — Plugin API expansion and PHP 8.5 support
27 changes.
This period focused on significantly expanding the plugin ecosystem by introducing comprehensive event handler interfaces for analysis hooks and taint control, alongside refactoring event classes into immutable value objects. Concurrently, the project modernized its infrastructure by adding extensive type stubs and callmap updates for PHP 8.5, while also enhancing the language server with in-memory caching and standardized progress reporting.
Features
Add CLI commands to manage Psalm plugins
Psalm now includes three new console commands—\enable\, \disable\, and \show\—allowing users to manage plugins directly from the command line. The \enable\ and \disable\ commands accept a plugin name (either a fully qualified class name or a composer package name) and an optional \-c\ flag to specify a config file path, providing immediate feedback on whether a plugin was successfully toggled or was already in the desired state. The \show\ command lists both currently enabled and available plugins in a structured table format, helping users audit their plugin configuration.
src/Psalm/Internal/PluginManager/Command · high confidence
Add Hack conformance harness to verify type-variable behavior
A new conformance harness under \bin/hack-conformance\ ensures Psalm's class-template type-variable feature matches the real Hack typechecker (HHVM). It includes a runner (\run.php\) and helper library (\lib.php\) that execute pinned HHVM fixtures via Docker, comparing HHVM's type-checking verdicts against expected outcomes. The harness is integrated into the PHPUnit suite via \tests/HackConformanceTest.php\, which runs these checks as standard unit tests (skipping cleanly if Docker or HHVM is unavailable). Additionally, a \track-upstream.php\ script monitors the upstream Hack test directories for drift, alerting developers to changes in the reference behavior.
bin/hack-conformance · high confidence
Add PHAR distribution assets for standalone Psalm installation
New files have been added to the assets/psalm-phar directory to support a standalone PHAR distribution of Psalm. This includes a README explaining that the PHAR allows installation without composer conflicts, and a .gitignore file configured to exclude composer artifacts (composer.phar, vendor/, composer.lock) from version control, facilitating a self-contained distribution method.
assets · high confidence
Add SourceControlInfo classes for Git repository metadata
New classes have been added to the \src/Psalm/SourceControl\ directory to represent Git repository information, including \SourceControlInfo\ as an abstract base, \GitInfo\ for branch and remote details, \CommitInfo\ for HEAD commit data (now including a date field), and \RemoteInfo\ for remote repository URLs. These classes provide a structured way to access and serialize Git metadata, likely for integration with coverage reporting tools like Coveralls.
src/Psalm/SourceControl · high confidence
Add composer-based echo-checker plugin example
The examples/plugins/composer-based directory now includes a new echo-checker plugin that demonstrates how to implement the AfterStatementAnalysisInterface. This example plugin registers a hook to detect when the PHP echo statement is used with mixed or non-literal string types, reporting an ArgumentTypeCoercion issue to help users identify potential security or type-safety problems in their code.
examples/plugins/composer-based · high confidence
Add template analysis example for view classes
The examples directory now includes a new template analysis tool consisting of \TemplateScanner.php\ and \TemplateAnalyzer.php\. This example demonstrates how to scan PHP files for a custom \@variablesfrom\ docblock tag to extract method references, queue the associated classes for scanning, and then analyze the file's statements within the context of a virtual view class (\Your\\View\\Class\). It serves as a practical guide for implementing custom static analysis logic that bridges standard PHP code with template-like view structures.
examples · high confidence
Add type provider for DOMDocument properties
Psalm now understands the type of the \documentElement\ property on \DOMDocument\ objects, returning \DOMElement\|null\. This prevents false-positive nullable issues when accessing this property, as the provider explicitly handles the union type with the \ignore\_nullable\_issues\ flag.
src/Psalm/Internal/Provider/PropertyTypeProvider · high confidence
Comprehensive PHP stubs for core classes, functions, and language features
This release introduces a complete set of new stub files that define the signatures and types for PHP's core language constructs, standard library functions, and internal classes. The changes include detailed type definitions for generic functions (such as array manipulation and string processing) in CoreGenericFunctions.phpstub, class definitions for iterators and array access in CoreGenericIterators.phpstub and CoreGenericClasses.phpstub, and immutable class definitions for DateTime and exceptions in CoreImmutableClasses.phpstub. It also adds version-specific stubs for PHP 7.4 through 8.5, covering new features like enums (Php81.phpstub), lazy objects (Php84.phpstub), and the NoDiscard attribute (Php85.phpstub), as well as stubs for core attributes and the PhpParser library.
stubs · high confidence
Improved return type inference for array manipulation functions
Psalm now provides precise return type inference for several array functions, including array\_chunk, array\_column, array\_combine, array\_fill\_keys, array\_fill, array\_filter, array\_map, array\_merge, array\_pad, array\_pop, array\_shift, and array\_rand. These new providers analyze input types and arguments to return more specific types (such as lists, keyed arrays, or non-empty arrays) instead of generic arrays, reducing false positives and improving type safety for users working with array operations.
src/Psalm/Internal/Provider/ReturnTypeProvider · high confidence
In-memory project cache provider for language server
The language server now includes an in-memory implementation of the project cache provider. This new class overrides the standard project cache behavior to track the last successful run time in memory, enabling file diffing capabilities immediately after the first successful analysis run without relying on persistent storage.
src/Psalm/Internal/LanguageServer/Provider · high confidence
Initial project scaffolding and configuration
The repository has been initialized with essential project configuration files, including a Code of Conduct, contributing guidelines, and an MIT license. Development standards are enforced via \.editorconfig\ and \phpcs.xml\ (using PSR-2 and Slevomat rules), while CI infrastructure is configured for AppVeyor. The PHAR build process is defined in \box.json.dist\, and the XML configuration schema is established in \config.xsd\.
(repo-wide) · high confidence
Introduce CustomTraverser for AST node traversal
A new \CustomTraverser\ class has been added to the internal PHP traverser component. This class extends \PhpParser\\NodeTraverser\ and implements custom logic for recursively traversing PHP Abstract Syntax Tree (AST) nodes. It handles both single nodes and arrays of nodes, invoking visitor \enterNode\ and \leaveNode\ methods while supporting node replacement, child traversal control, and traversal stopping. This provides a specialized mechanism for analyzing and modifying PHP code structures within the Psalm tool.
src/Psalm/Internal/PhpTraverser · high confidence
Introduce custom Docker image with PHP 8.4 and JIT optimizations
The project now ships a dedicated Dockerfile in \bin/docker\ that builds PHP 8.4.18 from source on Debian Bookworm, applying a custom \deepbind.patch\ to enable \RTLD\DEEPBIND\ for extension loading. The image includes a suite of helper scripts (\docker-php-ext-\\, \docker-php-source\) for managing extensions and source, and is pre-configured with \igbinary\, \jemalloc\, and an \opcache\ setup tuned for Just-In-Time (JIT) compilation. An \entrypoint.sh\ is provided to run Psalm with the \--force-jit\ flag, ensuring the analysis benefits from the compiled runtime optimizations.
bin/docker · high confidence
Introduces dedicated storage classes for assertions, attributes, and PHP 8.4 property hooks
Psalm now uses new, immutable storage classes in the \src/Psalm/Storage\ directory to represent internal analysis data more robustly. \Assertion\ replaces string-based checks with typed objects, enabling more precise type narrowing and negation logic. \AttributeStorage\ and \AttributeArg\ provide structured storage for PHP attributes, including their arguments and locations. \PropertyHookStorage\ adds support for PHP 8.4 property hooks (get/set), while \Possibilities\ manages assertion rules for variables. These changes also include \CustomMetadataTrait\ for extensible storage metadata and \UnserializeMemoryUsageSuppressionTrait\ to optimize memory usage during caching.
src/Psalm/Storage · high confidence
Introduction of Virtual Node classes for AST differentiation
Psalm now includes a comprehensive set of 'Virtual' node classes (e.g., \VirtualBitwiseAnd\, \VirtualClass\) in the \src/Psalm/Node\ directory. These classes extend PhpParser's standard AST nodes and implement the \VirtualNode\ interface, enabling the analyzer to distinguish between real source code nodes and synthetic ones generated by plugins or internal logic.
src/Psalm/Node · high confidence
New AlgebraAnalyzer for detecting redundant and paradoxical conditions
Psalm now includes an AlgebraAnalyzer component that evaluates logical conditions to identify redundant assertions (e.g., checking the same condition twice in sequence) and paradoxical conditions (e.g., a condition that contradicts a previously established one). This improves the accuracy of static analysis by flagging logically impossible or unnecessary code paths.
src/Psalm/Internal/Analyzer · high confidence
New CI scripts for Phar builds, Docker multi-arch images, and real-project testing
Added a suite of scripts in bin/ci to streamline the release and testing pipeline. build-docker.php and push-docker.php handle building and publishing multi-architecture (arm64/amd64) Docker images with registry caching, while build-phar.sh and github-deploy-phar.sh manage the compilation, GPG signing, and deployment of the Phar package. test-with-real-projects.sh enables end-to-end validation against external codebases (PHPUnit, Laravel, PSL, Collections) using branch-specific baselines, and apply-composer-build-patch.sh allows developers to fetch and apply generated callmap patches from CI. Additional utilities include generate\_testsuites.php for parallelizing PHPUnit test runs, improve\_class\_alias.php for patching php-scoper, and a composer-require-checker-config.json for stricter dependency validation.
bin/ci · high confidence
New CLI command classes for language server, plugins, psalter, refactor, and review
The CLI entry points have been refactored into dedicated command classes. A new \LanguageServer\ class handles the language server mode with its own set of options (e.g., \--map-folder\, \--on-open-debounce-ms\). A \Plugin\ class wraps plugin management commands (\show\, \enable\, \disable\) using Symfony Console. \Psalm\, \Psalter\, and \Refactor\ are now distinct classes with their own argument parsing and help text. A new \Review\ class introduces the \psalm-review\ command, which parses a JSON report and iterates through issues in an IDE (VS Code, PhpStorm, or code-server) for manual review.
src/Psalm/Internal/Cli · high confidence
New FormulaGenerator for algebraic assertion analysis
Psalm introduces a new FormulaGenerator class in the Internal Algebra component to handle the generation of logical clauses from conditional expressions. This new capability allows the static analyzer to more accurately process complex boolean logic, including the transformation of negated OR conditions into AND forms (De Morgan's laws) and the handling of multi-variable isset checks, thereby improving the precision of type inference in conditional branches.
src/Psalm/Internal/Algebra · high confidence
New example plugins for code quality and security enforcement
The examples/plugins directory now includes several new plugin implementations demonstrating advanced Psalm capabilities. ClassUnqualifier automatically rewrites fully qualified class names to use aliases. FunctionCasingChecker enforces correct casing for functions and methods, reporting IncorrectFunctionCasing issues. InternalChecker detects Psalm\\Internal classes missing the @internal annotation and can auto-fix them. PreventFloatAssignmentChecker blocks assignments to float values. SafeArrayKeyChecker removes HTML taints for array keys explicitly named 'safe\_key'. StringChecker encourages the use of ::class constants over string literals and detects undefined methods in concatenated class references. TaintActiveRecords automatically marks property accesses on classes in the app\\models namespace as tainted to improve security analysis.
examples/plugins · high confidence
New internal classes for collecting CI environment and Git repository information
Psalm now includes three new internal classes in the ExecutionEnvironment namespace to gather build context: BuildInfoCollector extracts CI-specific variables (such as job IDs, branch names, and repository slugs) from Travis CI, CircleCI, AppVeyor, Jenkins, Scrutinizer, and GitHub Actions; GitInfoCollector runs local Git commands to retrieve the current branch, commit details, and remote URLs; and SystemCommandExecutor provides a wrapper for executing system commands, including a check to ensure the exec function is available. These components enable Psalm to attach accurate source-control and continuous-integration metadata to its output.
src/Psalm/Internal/ExecutionEnvironment · high confidence
New internal infrastructure for caching, serialization, and analysis
Psalm introduces a suite of new internal classes to support advanced caching and analysis capabilities. The new Cache and RuntimeCaches classes centralize cache management, supporting persistent storage with consolidation and configurable array caching. GzipSerializer and Lz4Serializer provide new compression options for the parser cache to reduce storage size and improve performance. The Algebra and Clause classes implement immutable data structures for handling logical clauses and simplifying CNF formulae during type analysis. Additionally, the EventDispatcher class provides a centralized mechanism for plugin event handling, while Preloader and PreloaderList optimize startup performance by preloading classes. The ErrorHandler class converts PHP errors and warnings into exceptions for more robust error reporting, and the MethodIdentifier class replaces string-based method references with typed objects for better type safety.
src/Psalm/Internal · high confidence
New plugin event handler interfaces for analysis hooks and taint control
The \src/Psalm/Plugin/EventHandler\ directory now exposes a comprehensive set of new interfaces that allow plugins to hook into specific stages of the static analysis process and control security taint tracking. Plugins can now intercept analysis before and after statements, expressions, files, and function calls (e.g., \BeforeStatementAnalysisInterface\, \AfterExpressionAnalysisInterface\), and provide custom logic for function/method/property existence, parameters, return types, and visibility (e.g., \FunctionExistenceProviderInterface\, \MethodParamsProviderInterface\). Additionally, new interfaces for taint management (\AddTaintsInterface\, \RemoveTaintsInterface\) and issue suppression (\BeforeAddIssueInterface\) enable plugins to modify security findings and prevent specific issues from being reported.
src/Psalm/Plugin/EventHandler · high confidence
New report formats and enhanced console output
Psalm now includes several new report formats: SARIF, CodeClimate, JUnit, SonarQube, Checkstyle, Pylint, and Emacs. The console report has been improved with colorized file names and line numbers, clickable editor links (when xdebug.file\_link\_format is set), and support for multiline TaintedInput issues. Additionally, a new ByIssueLevelAndType report sorts issues by severity and type, and the Compact report now uses a table layout for better readability.
src/Psalm/Report · high confidence
New stub generation and build tooling for PHP 8.5
The \bin/stubs\ directory now contains a complete toolchain for generating and maintaining Psalm's internal callmaps and stubs. This includes \build\_docker.php\ to construct Docker images for PHP versions 7.0 through 8.5 with specific extension configurations, and scripts like \gen\_base\_callmap.php\ and \gen\_callmap.php\ to automatically generate and normalize type maps from the running PHP environment and hand-written overrides. The addition of \update-property-map.php\ and \update\_signaturemap\_from\_other\_tool.php\ further automates the synchronization of property and signature data, ensuring the type dictionaries remain accurate for the newly supported PHP 8.5 version.
bin/stubs · high confidence
New stubs for AMQP, APCu, Decimal, DOM, DS, FFI, GEOS, GMP, IBM DB2, Intl, Memcached, MongoDB, MySQLi, PDO, and Random extensions
This update adds comprehensive type stubs for a wide range of PHP extensions, significantly improving static analysis coverage. New stubs are introduced for the AMQP extension (including constants and the AMQPBasicProperties class), APCu (constants and APCUIterator), the Decimal library (full class and constants), the DS data structures library (Collection, Deque, etc.), GEOS (geometry constants), GMP (GMP class), IBM DB2 (db2\_autocommit function), Intl (NumberFormatter constants), Memcached (constants and Memcached class), MongoDB (BSON Document, Iterator, PackedArray, and Driver CursorInterface), MySQLi (mysqli, mysqli\_result, mysqli\_stmt classes and constants), PDO (PDO, PDOStatement, PDOException classes and constants), and the PHP 8.2 Random extension (Randomizer, engines). Existing stubs for DOM, FFI, and PDO are also updated with refined types and signatures.
stubs/extensions · high confidence
Architecture
Language server architecture refactored to use internal protocol handlers and event emitters
The Language Server Protocol implementation has been restructured to use a new internal architecture. This includes a dedicated \ClientConfiguration\ class to manage client settings (such as debounce times and feature toggles), a \ClientHandler\ for sending requests and notifications, and a custom \EmitterInterface\/\EmitterTrait\ for event handling. The server now uses \ProtocolReader\ and \ProtocolWriter\ interfaces with \Message\ wrappers for JSON-RPC communication, and introduces a \PathMapper\ to handle path translation between the client and server. These changes improve the modularity and internal typing of the language server.
src/Psalm/Internal/LanguageServer · high confidence
Psalm internal codebase refactored into dedicated analysis and resolver classes
The internal analysis engine in src/Psalm/Internal/Codebase has been restructured into a set of specialized classes to improve modularity and maintainability. The monolithic analysis logic is now split into Analyzer.php for the main analysis orchestration, ClassLikes.php for class/interface/trait/enum handling, Functions.php for function storage and resolution, and ConstantTypeResolver.php for resolving constant expressions. New dedicated resolvers have been introduced: AssertionsFromInheritanceResolver.php handles assertion inheritance from parent classes and interfaces, and ClassConstantByWildcardResolver.php resolves class constants using wildcard patterns. The taint analysis infrastructure has been abstracted into DataFlowGraph.php, providing a common base for tracking data flow paths. This refactoring isolates specific concerns, making the codebase easier to extend and test without changing the external behavior of the static analysis tool.
src/Psalm/Internal/Codebase · high confidence
Refactor Language Server protocol handlers into dedicated Server classes
The Language Server Protocol method handlers have been reorganized from the main server class into dedicated \Server/TextDocument.php\ and \Server/Workspace.php\ classes. This change introduces specific handlers for text document lifecycle events (open, save, change, close) and workspace features, including \workspace/didChangeWatchedFiles\ which now triggers a full codebase reload when \composer.lock\ is modified, and \workspace/executeCommand\ to support single-file analysis commands.
src/Psalm/Internal/LanguageServer/Server · high confidence
Refactor PHP AST analysis into specialized PhpVisitor components
The internal PHP AST analysis pipeline in src/Psalm/Internal/PhpVisitor has been restructured into a suite of specialized visitors. This change introduces dedicated components for specific analysis tasks: AssignmentMapVisitor for tracking variable assignments within loops, CheckTrivialExprVisitor for identifying non-trivial expressions, CloningVisitor and ConditionCloningVisitor for node cloning and type preservation, NodeCleanerVisitor for clearing node data, OffsetShifterVisitor for adjusting AST node positions, ParamReplacementVisitor for renaming parameters and updating docblocks, PartialParserVisitor for parsing specific method sections from diffs, ReflectorVisitor for scanning class and function structures, ShortClosureVisitor for tracking used variables, SimpleNameResolver for resolving class and function names, TraitFinder for locating trait definitions, TypeMappingVisitor for mapping fake types to real types, and YieldTypeCollector for collecting generator yield types. This modularization improves the maintainability and precision of Psalm's static analysis capabilities.
src/Psalm/Internal/PhpVisitor · high confidence
Refactor reflection logic into dedicated scanner and resolver classes
The monolithic reflection logic in the Reflector directory has been broken out into specialized components: AttributeResolver, ClassLikeDocblockParser, ClassLikeNodeScanner, ExpressionResolver, ExpressionScanner, FunctionLikeDocblockParser, FunctionLikeDocblockScanner, FunctionLikeNodeScanner, and TypeHintResolver. This restructuring separates the concerns of parsing docblocks, resolving PHP attributes, scanning AST nodes for classes and functions, and resolving type hints, making the reflection pipeline more modular and maintainable.
src/Psalm/Internal/PhpVisitor/Reflector · high confidence
Refactor statement analysis into dedicated analyzer classes
Psalm's statement analysis logic has been broken out of the monolithic StatementsAnalyzer into dedicated, single-responsibility classes (such as BreakAnalyzer, ContinueAnalyzer, DeclareAnalyzer, EchoAnalyzer, GlobalAnalyzer, ReturnAnalyzer, StaticAnalyzer, and UnsetAnalyzer). This architectural change improves code maintainability and allows for more granular control over how specific PHP constructs are analyzed, tracked, and reported.
src/Psalm/Internal/Analyzer/Statements · high confidence
Refactor type analysis into dedicated visitor classes
Psalm now uses a set of specialized internal visitor classes in src/Psalm/Internal/TypeVisitor to handle type checking and manipulation. This change introduces new components such as TypeChecker for validating types and reporting issues, TypeScanner for queueing class scanning, and various visitors (e.g., ContainsClassLikeVisitor, TemplateTypeCollector) for specific type queries and transformations. This modularizes the type analysis logic, separating concerns like object containment checks, literal detection, and template parameter handling into distinct, reusable classes.
src/Psalm/Internal/TypeVisitor · high confidence
Refactored assignment analysis into dedicated analyzers
The assignment analysis logic has been restructured into three new dedicated classes: ArrayAssignmentAnalyzer, InstancePropertyAssignmentAnalyzer, and StaticPropertyAssignmentAnalyzer, along with a supporting AssignedProperty value object. This change replaces the previous monolithic or less-structured approach with specialized handlers for array dimension assignments, instance property assignments, and static property assignments, improving code organization and maintainability for Psalm's type-checking engine.
src/Psalm/Internal/Analyzer/Statements/Expression/Assignment · high confidence
Refactored binary operator analysis into dedicated analyzer classes
The binary operator analysis logic in Psalm has been restructured from a monolithic analyzer into a set of specialized classes (AndAnalyzer, OrAnalyzer, CoalesceAnalyzer, ConcatAnalyzer, ArithmeticOpAnalyzer, and NonComparisonOpAnalyzer). This refactoring improves the maintainability and accuracy of type inference for logical, arithmetic, concatenation, and null-coalescing operations by isolating their specific analysis rules and side-effect handling.
src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp · high confidence
Refactored configuration file filtering and issue handling into dedicated classes
The configuration system has been restructured to improve modularity and maintainability. File filtering logic is now encapsulated in a hierarchy of classes: \FileFilter\ serves as the base for path and pattern matching, with specialized subclasses \ProjectFileFilter\ (handling project source files and ignore rules), \ErrorLevelFileFilter\ (managing per-file error levels), and \TaintAnalysisFileFilter\ (for taint analysis scope). Additionally, a new \IssueHandler\ class centralizes the logic for determining the reporting level for various issue types (files, classes, methods, properties, etc.) based on these filters, and a \Creator\ class handles the generation of default configuration files. This change separates concerns within the \src/Psalm/Config\ directory, making the configuration loading and application process more explicit and easier to extend.
src/Psalm/Config · high confidence
Refactored expression fetch analysis into dedicated analyzer classes
The monolithic statement analysis logic for fetching variables, constants, array elements, and properties has been split into five dedicated classes within the \src/Psalm/Internal/Analyzer/Statements/Expression/Fetch\ directory: \VariableFetchAnalyzer\, \ConstFetchAnalyzer\, \ArrayFetchAnalyzer\, \AtomicPropertyFetchAnalyzer\, \InstancePropertyFetchAnalyzer\, and \StaticPropertyFetchAnalyzer\. This architectural change isolates the specific type-inference and issue-reporting logic for each fetch type, improving code maintainability and allowing for more granular analysis of variable scopes, constant definitions, array offsets, and property access patterns.
src/Psalm/Internal/Analyzer/Statements/Expression, src/Psalm/Internal/Analyzer/Statements/Expression/Fetch · high confidence
Refactored function and method call analysis into specialized sub-analyzers
The logic for analyzing function and method calls has been split from the monolithic CallAnalyzer into dedicated classes within the src/Psalm/Internal/Analyzer/Statements/Expression/Call directory. This refactoring introduces ArgumentAnalyzer for validating individual argument types, ArgumentsAnalyzer for handling argument lists and named arguments, ArrayFunctionArgumentsAnalyzer for specialized array function logic (like array\_map and array\_push), ArgumentMapPopulator for tracking argument positions, and ClassTemplateParamCollector for resolving template parameters. This structural change improves code maintainability and allows for more granular analysis of call sites.
src/Psalm/Internal/Analyzer/Statements/Expression/Call · high confidence
Refactored if/else analysis into dedicated analyzer classes
The logic for analyzing if, else, and elseif blocks has been extracted from the monolithic IfElseAnalyzer into three new, dedicated classes: IfAnalyzer, ElseAnalyzer, and ElseIfAnalyzer. This structural change improves code maintainability and allows for more precise handling of type reconciliation and context updates within each specific branch type, ensuring that variable scopes and reference constraints are managed more accurately during static analysis.
src/Psalm/Internal/Analyzer/Statements/Block/IfElse · high confidence
Refactored internal providers into a new centralized caching and plugin architecture
The internal provider layer has been restructured to introduce dedicated caching providers for class and file storage (ClassLikeStorageCacheProvider, FileStorageCacheProvider) and a comprehensive FileReferenceCacheProvider to persist dependency graphs for efficient diff-mode analysis. The previous monolithic providers have been replaced by specialized, plugin-extensible handlers for function and method analysis (FunctionReturnTypeProvider, MethodParamsProvider, etc.), which now register specific return-type and parameter providers for standard library functions. Additionally, a new FakeFileProvider has been added to support in-memory file mocking for testing, and the FileProvider now utilizes modern PHP iterators for directory scanning.
src/Psalm/Internal/Provider · high confidence
Refactored method call analysis into specialized internal classes
Psalm's internal method call analysis logic has been restructured into a set of dedicated classes within the \src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method\ directory. This change introduces \AtomicMethodCallAnalyzer\ and \ExistingAtomicMethodCallAnalyzer\ to handle the core analysis of method calls, while extracting specific concerns into \MethodCallProhibitionAnalyzer\ (for deprecation and internal visibility checks), \MethodCallPurityAnalyzer\ (for mutation-free and unused call detection), \MethodCallReturnTypeFetcher\ (for resolving return types), \MethodVisibilityAnalyzer\ (for access control checks), and \MissingMethodCallHandler\ (for magic and pseudo-methods). This refactoring improves the modularity and maintainability of how Psalm analyzes method invocations, including support for first-class callables and improved handling of intersection types and mixins.
src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method · high confidence
Refactored plugin management into dedicated internal classes
The plugin manager logic has been restructured into four new internal classes: ComposerLock, ConfigFile, PluginList, and PluginListFactory. ComposerLock now handles parsing composer.lock files to identify available plugins, while ConfigFile manages reading and writing plugin entries to the Psalm XML configuration. PluginList coordinates these sources to resolve, enable, and disable plugins, and PluginListFactory orchestrates their instantiation. This change isolates plugin discovery and configuration logic from the main PluginManager, improving code organization and maintainability.
src/Psalm/Internal/PluginManager · high confidence
Refactored return type analysis into dedicated analyzer and collector classes
The logic for analyzing function return types has been extracted from the main FunctionLike analyzer into two new internal classes: ReturnTypeAnalyzer and ReturnTypeCollector. This change restructures how Psalm inspects function bodies to determine inferred return types, handling control flow, yield expressions, and type inference in a more modular way, which supports more granular issue reporting and future enhancements to return type checking.
src/Psalm/Internal/Analyzer/FunctionLike · high confidence
Refactored static method call analysis into dedicated analyzer classes
The static method call analysis logic has been restructured into two new internal classes, AtomicStaticCallAnalyzer and ExistingAtomicStaticCallAnalyzer, located in the src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod directory. AtomicStaticCallAnalyzer now handles the initial resolution of the class type (supporting TNamedObject, TClassString, TDependentGetClass, TLiteralClassString, and TTemplateParam) and delegates to ExistingAtomicStaticCallAnalyzer for existing method analysis. ExistingAtomicStaticCallAnalyzer manages the core analysis of static calls, including handling parent keyword calls with template extended parameters, collecting class template parameters, and enforcing method call prohibitions. This change improves the modularity and maintainability of static method analysis within Psalm.
src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod · high confidence
Refactored type reconciliation and parsing into dedicated internal classes
The type reconciliation logic in \src/Psalm/Internal/Type\ has been restructured to improve maintainability and performance. The monolithic \Reconciler\ class has been broken apart into specialized components: \AssertionReconciler\ and \NegatedAssertionReconciler\ now handle positive and negative assertion logic respectively, delegating to \SimpleAssertionReconciler\ and \SimpleNegatedAssertionReconciler\ for straightforward cases. A new \ClosedInheritanceToUnion\ utility maps closed inheritance hierarchies to unions during reconciliation, and \ArrayType\ provides a dedicated structure for inferring array type details. Additionally, the type parsing system has been migrated to an internal namespace, introducing \ParseTree\ and \ParseTreeCreator\ to manage the parsing of complex type tokens into a structured tree.
src/Psalm/Internal/Type · high confidence
Behavioural changes
Assertion types are now immutable value objects
Psalm's internal assertion system has been refactored from string-based representations to a set of immutable, final PHP classes in the \Psalm\\Storage\\Assertion\ namespace (e.g., \IsType\, \HasMethod\, \IsIdentical\). This change ensures that assertions are treated as distinct, immutable value objects with explicit negation logic, improving type safety and clarity in how Psalm stores and reconciles type information.
src/Psalm/Storage/Assertion · high confidence
Emit all stubs discovered by Psalm during analysis
Psalm now automatically generates and emits stubs for all classes, interfaces, traits, functions, and constants discovered during analysis, excluding internal Psalm code and already-stubbed items. This ensures that the generated stubs accurately reflect the full scope of the analyzed codebase, including file-defined functions and constants, without requiring manual intervention.
src/Psalm/Internal/Stubs · high confidence
HTML entity functions now respect PHP 8.1+ default encoding flags
The new HtmlFunctionTainter component updates taint analysis for html\_entity\_decode, htmlspecialchars\_decode, htmlentities, and htmlspecialchars to account for PHP 8.1+ changes where the default encoding flags include ENT\_QUOTES. When these functions are called without an explicit second argument on PHP 8.1 or later, the analysis now correctly marks the output as tainted with both INPUT\_HTML and INPUT\_HAS\_QUOTES, whereas previous versions only marked INPUT\_HTML. This ensures more accurate security detection for quote-related injection vectors in modern PHP environments.
src/Psalm/Internal/Provider/AddRemoveTaints · high confidence
Improved type checking for array functions
Psalm now provides specific parameter type providers for several array functions, including array\_filter, array\_multisort, and various array\_diff/intersect variants. This change enables more precise validation of arguments, such as detecting invalid third arguments in array\_filter when the callback is null, and ensuring correct parameter types for sorting and comparison operations.
src/Psalm/Internal/Provider/ParamsProvider · high confidence
Internal refactoring of docblock and code-manipulation classes
Classes in the \Psalm\\Internal\\FileManipulation\ namespace (such as \ClassDocblockManipulator\, \FunctionDocblockManipulator\, \PropertyDocblockManipulator\, \FileManipulationBuffer\, and \CodeMigration\) have been moved from the public \Psalm\ namespace to the internal \Psalm\\Internal\ namespace. This change restricts these implementation details to internal use, meaning external tools or plugins should no longer rely on these specific classes for modifying PHP code or docblocks.
src/Psalm/Internal/FileManipulation · high confidence
Internal type alias representation classes introduced
The internal type alias system now uses dedicated classes (ClassTypeAlias, InlineTypeAlias, LinkableTypeAlias) to represent different alias types, replacing the previous approach. These classes are marked as immutable and internal, providing a more structured way to handle type alias data within Psalm's internal type resolution.
src/Psalm/Internal/Type/TypeAlias · medium confidence
Introduce AST-aware file differ for precise language server diffs
Psalm now uses a new set of internal classes in \src/Psalm/Internal/Diff\ to compute differences between PHP files. Instead of simple line-by-line comparison, the new \FileDiffer\ and \FileStatementsDiffer\ leverage the Myers diff algorithm on the PHP-Parser AST to distinguish between signature changes (e.g., method name, property type) and body changes. This allows the language server to provide more accurate diagnostics and refactoring suggestions by understanding the structural context of code changes rather than just text offsets.
src/Psalm/Internal/Diff · high confidence
Introduce dedicated Aliases class for tracking file-level imports
Psalm now uses a dedicated \Psalm\\Aliases\ class to store and manage file-level namespace imports (use statements), functions, and constants. This change replaces the previous approach of using raw arrays or less structured storage within the codebase, providing a more robust and type-safe way to resolve symbols during static analysis.
src/Psalm · high confidence
Introduce dedicated DataFlow graph structures for taint tracking
Psalm now uses a new internal data structure for tracking data flow, replacing the previous ControlFlowGraph with a dedicated DataFlowGraph. This change introduces specific node types—DataFlowNode, TaintSource, and TaintSink—and a Path class to represent taint propagation paths with unescaped and escaped taint lists. This structural shift supports more precise taint analysis, including the ability to add taint sources from plugins and handle immutable unions, improving the accuracy of security-related static analysis.
src/Psalm/Internal/DataFlow · high confidence
Introduce new Amp-based parallel processing infrastructure
Psalm now uses a new internal parallel processing system built on the Amp library and the \Amp\\Parallel\ components. This change introduces a new \Fork\ namespace containing a \Pool\ for managing worker processes, a \ForkContext\ for handling inter-process communication (IPC) and serialization (including optional \igbinary\ support), and a suite of specific task classes (\AnalyzerTask\, \ScannerTask\, \InitAnalyzerTask\, \ShutdownAnalyzerTask\, etc.) that define the work units for code analysis and scanning. The \PsalmRestarter\ has been updated to manage opcache and extension settings specifically for this new parallel execution model.
src/Psalm/Internal/Fork · high confidence
Introduce specialized code location classes for docblocks, parse errors, and raw positions
Psalm now uses dedicated subclasses of CodeLocation—DocblockTypeLocation, ParseErrorLocation, and Raw—to provide more precise and context-aware location tracking. DocblockTypeLocation exposes the specific line number of a docblock type annotation, ParseErrorLocation accurately maps parser errors to their file positions and line numbers, and Raw provides a generic location based on file content offsets. These changes improve the accuracy of error reporting and code analysis by ensuring that location data reflects the specific context in which it was generated.
src/Psalm/CodeLocation · high confidence
Introduce specific exception classes for analysis errors
The \src/Psalm/Exception\ directory now contains a dedicated set of exception classes (such as \CircularReferenceException\, \UnpopulatedClasslikeException\, and \UnresolvableConstantException\) to replace generic error handling. This allows the tool to distinguish between different failure modes during static analysis, providing more precise error reporting and enabling better handling of specific scenarios like circular references or unpopulated class definitions.
src/Psalm/Exception · high confidence
Modernized LSP progress reporting with token-based notifications
The progress reporting mechanism in the Language Server has been updated to use the standard LSP \$/progress\ notification protocol. The new \Progress\ class sends structured notifications containing a unique token and specific actions (begin, report, end), allowing clients to track multiple concurrent operations. A \LegacyProgress\ implementation is also provided for compatibility, which continues to use the older \telemetry/event\ notification method. This change ensures that progress updates are properly scoped and supported by LSP-compliant editors.
src/Psalm/Internal/LanguageServer/Client/Progress · high confidence
New internal client method handlers for diagnostics and workspace configuration
The Language Server Client now exposes dedicated internal classes (TextDocument and Workspace) to handle specific LSP protocol methods. The TextDocument class provides a handler for publishing diagnostics from the server to the client, respecting the client's configuration settings. The Workspace class adds a method to request configuration settings from the client, allowing the server to fetch specific configuration sections. These changes structure the client-side protocol handling more explicitly.
src/Psalm/Internal/LanguageServer/Client · high confidence
New plugin architecture and improved Shepherd reporting
This change introduces a new plugin registration model via the \PluginEntryPointInterface\ and \PluginRegistrationSocket\, replacing the previous \RegistrationInterface\ to allow plugins to declare custom scanners, analyzers, and file extensions early. It also adds new internal classes (\ArgTypeInferer\, \DynamicFunctionStorage\, \DynamicTemplateProvider\) to support dynamic function storage and template handling. Additionally, the Shepherd reporting mechanism has been updated to send a list of issues instead of an array with integer keys, include package versions in the payload, follow HTTP redirects, and output debug information to STDERR for better visibility of errors and SSL issues.
src/Psalm/Plugin · high confidence
Plugin event classes are now immutable and final
All event classes in the \src/Psalm/Plugin/EventHandler/Event\ directory have been converted to immutable, final value objects. Constructor properties are now declared as \private readonly\, and mutable setter methods (such as \setFileReplacements\ and \setStmt\) have been removed in favor of passing state through the constructor. This change ensures that event data cannot be modified after creation, providing a more stable and predictable interface for plugin developers hooking into the analysis lifecycle.
src/Psalm/Plugin/EventHandler/Event · high confidence
Psalm issue reporting system refactored with granular issue types and structured data
The static analysis engine's issue reporting system has been completely restructured to provide more granular and specific error detection. The abstract \CodeIssue\ base class now defines a standardized structure with \ERROR\LEVEL\ and \SHORTCODE\ constants, and its \toIssueData\ method has been updated to return a structured \IssueData\ object containing detailed location, snippet, and taint trace information. This foundation supports a massive expansion of specific issue classes—such as \AbstractInstantiation\, \ConstructorSignatureMismatch\, \DocblockTypeContradiction\, and numerous \Invalid\\ and \Possibly\*\ variants—which replace broader, generic error categories. This change allows users to filter, suppress, and understand type safety violations with much higher precision.
src/Psalm/Issue · high confidence
Refactor constant expression parsing into immutable value objects
The internal constant expression scanner has been refactored to use a set of new, immutable, and readonly classes (such as UnresolvedBinaryOp, UnresolvedTernary, and ClassConstant) to represent constant structures. This change improves type safety and immutability within the scanner, ensuring that constant expressions are handled more robustly during static analysis.
src/Psalm/Internal/Scanner/UnresolvedConstant · medium confidence
Refactor scope tracking into dedicated internal classes
Psalm now uses specific internal classes (CaseScope, FinallyScope, IfConditionalScope, IfScope, LoopScope, SwitchScope) to manage variable scope and type inference for different control structures, replacing the previous monolithic approach. This structural change improves the precision of type analysis for variables within if/else blocks, loops, switch statements, and finally blocks, leading to more accurate detection of undefined or reassigned variables.
src/Psalm/Internal/Scope · high confidence
Refactor type parsing into dedicated ParseTree node classes
The internal type parser in src/Psalm/Internal/Type/ParseTree has been restructured to use specific, final classes for each parse tree node type (such as CallableTree, UnionTree, GenericTree, and Value). This change introduces a more explicit internal representation for parsed type structures, improving code clarity and maintainability for the type-checking engine without altering external behavior.
src/Psalm/Internal/Type/ParseTree · high confidence
Refactored control-flow analysis into dedicated block analyzers
Psalm's analysis of control-flow structures (if/else, switch, loops, try/catch) has been reorganized from monolithic classes into dedicated, focused analyzers (DoAnalyzer, ForAnalyzer, ForeachAnalyzer, IfConditionalAnalyzer, IfElseAnalyzer, LoopAnalyzer, SwitchAnalyzer, SwitchCaseAnalyzer, TryAnalyzer). This change improves the precision of type inference and variable tracking within these blocks, reducing false positives for unused variables and improving handling of complex conditions, loops, and exception handling.
src/Psalm/Internal/Analyzer/Statements/Block · high confidence
Refactored docblock scanning into dedicated internal data structures
The internal docblock scanning logic in \src/Psalm/Internal/Scanner\ has been restructured to use specific data classes for storing parsed information. New classes \ClassLikeDocblockComment\, \FunctionDocblockComment\, \VarDocblockComment\, and \ParsedDocblock\ now hold the extracted metadata (such as templates, mixins, taint flows, and visibility overrides) that were previously managed by the \DocblockParser\. The \DocblockParser\ itself has been simplified to focus on raw tag extraction, while \FileScanner\ and \PhpStormMetaScanner\ have been updated to integrate with this new structure, improving the organization of how Psalm processes and stores docblock data.
src/Psalm/Internal/Scanner · high confidence
Refactored progress reporting with new UI and rate-limiting
The progress output system has been restructured into a new class hierarchy (Progress, LongProgress, DefaultProgress, DebugProgress, VoidProgress) to improve clarity and performance. For users scanning large projects (over 1,500 files), the default progress bar now uses a horizontal Unicode bar that is rate-limited to update at most once every 0.1 seconds, reducing terminal flickering and I/O overhead. The output now clearly distinguishes between scanning and analyzing phases, and includes a visual progress bar with percentage completion. A VoidProgress implementation allows for completely silent operation when needed.
src/Psalm/Progress · high confidence
Refactored type comparison logic into specialized comparator classes
Psalm's internal type comparison engine has been restructured by extracting specific comparison logic into dedicated classes within the \src/Psalm/Internal/Type/Comparator\ directory. This change introduces \ArrayTypeComparator\, \AtomicTypeComparator\, \CallableTypeComparator\, \ClassLikeStringComparator\, \GenericTypeComparator\, \IntegerRangeComparator\, \KeyedArrayComparator\, and \ObjectComparator\. For users, this architectural shift underpins improved accuracy in type checking, particularly for complex scenarios involving integer ranges, callable signatures, generic objects, and keyed arrays, while maintaining the same external static analysis behavior.
src/Psalm/Internal/Type/Comparator · high confidence
Refactored type system internals to use dedicated classes and traits for atomic types
The internal type representation in Psalm has been restructured to improve immutability and code organization. The \src/Psalm/Type/Atomic\ directory now contains dedicated classes for each atomic type (such as \TArray\, \TCallable\, \TClassString\, \TClosure\, and \TBool\) and shared logic has been extracted into traits like \CallableTrait\, \GenericTrait\, and \HasIntersectionTrait\. This change ensures that type objects are immutable, meaning operations that modify a type (like replacing template parameters or adding intersection types) return a new cloned instance rather than mutating the existing one. For users, this provides a more robust and predictable type system, reducing the risk of side effects during static analysis and improving the accuracy of type inference, particularly for complex generic and callable types.
src/Psalm/Type/Atomic · high confidence
Refactored type system to use immutable Union types and dedicated Atomic classes
The type representation in Psalm has been restructured to enforce immutability and improve type safety. The \Union\ class is now immutable, meaning type operations return new instances rather than modifying existing ones, while a new \MutableUnion\ class handles internal mutation during analysis. Atomic types (e.g., \TInt\, \TString\) are now distinct classes rather than string identifiers, and the \Reconciler\ has been updated to work with this new object-oriented type structure. This change ensures that type states are preserved correctly during static analysis, reducing side effects and improving the reliability of type inference.
src/Psalm/Type · high confidence
Robust JSON encoding with pretty-printing and invalid UTF-8 handling
The JSON reporting system now uses a dedicated encoder that supports pretty-printed output and automatically sanitizes invalid UTF-8 sequences in error messages. This prevents crashes when generating reports containing malformed strings, ensuring that JSON output is always valid and readable.
src/Psalm/Internal/Json · high confidence
Updated PHP 8.5 callmap with stricter AMQP return types
The \dictionaries/autogen/CallMap\_85.php\ file has been added to support PHP 8.5, introducing stricter type signatures for the AMQP extension compared to previous versions. Specifically, \amqpbasicproperties\ getter methods now return \null\|string\ or \int\ instead of \mixed\, and \amqpchannel\ methods like \basicrecover\ and \close\ now return \void\ with a \bool\ parameter for \requeue\, replacing the previous \mixed\ return types. This change improves type safety for static analysis tools when working with AMQP connections and channels in PHP 8.5.
dictionaries/autogen · high confidence
Updated PHP function signatures across versions 7.1–8.5
The PHP callmap dictionaries have been refreshed to cover PHP versions 7.1 through 8.5. This update adds type signatures for new functions introduced in these versions (such as \array\_find\_key\ in 8.4, \fiber\ methods in 8.1, and \json\_validate\ in 8.3) and corrects existing signatures to match current PHP behavior. Notable behavioral changes include \error\_get\last()\ now returning a \trace\ array in 8.5, several \imap\\*\ functions returning \true\ instead of \bool\ in 8.3, and stricter parameter types for functions like \idn\_to\ascii\ and \grapheme\\*\ in 8.4 and 8.5.
dictionaries/override · high confidence
Updated PHP version dictionaries and taint/impurity definitions
The dictionaries directory has been regenerated to include call maps for PHP 7.0 through 8.5, reflecting API changes such as stricter return types for AMQP properties and updated function signatures. Additionally, the taint analysis model has been refined: the InternalTaintSinkMap now explicitly marks functions like getimagesize, popen, and proc\_open as SSRF or shell sinks, and the ImpureFunctionsList has been expanded to include mail, socket\_shutdown, and readgzfile, ensuring more accurate static analysis for security and side-effect detection.
dictionaries · high confidence
Test coverage
Added comprehensive test suite for the Language Server; Added end-to-end tests for Psalm and Psalter commands; Added performance test fixtures for partial parsing benchmarks; Added test coverage for FileScanner global variable handling; Added test coverage for loop control flow analysis; Added test fixture for SuicidalAutoloader; Added test fixture for destructive autoloader behavior; Added test fixture for error detection scenarios; Added test fixture for taint graph output; Added test fixtures for class discovery in library directories; Added test fixtures for modular config support; Added test fixtures for plugin hook interfaces; Added test fixtures for trait method resolution and function loading; Added test helper classes for parser and project cache providers; Added test helper for progress output; Added test plugin fixtures for configuration and hook registration; Added test suite for template type analysis; Added test traits for code analysis validation; Added tests for Union type literal float detection; Added tests for cache invalidation scenarios; Added tests for codebase internal components; Added tests for declare statement analysis and dynamic property access; Added tests for file manipulation refactorings; Added tests for file update and caching behavior; Added tests for internal CallMap validation, CLI argument parsing, and JSON encoding; Added tests for return type providers; Added tests for taint-add and taint-remove plugin event handlers; Added unit tests for the Config subsystem; Expanded test coverage for static analysis features; Expanded test coverage for type reconciliation logic.
Dependencies
Initial composer.json manifests for Psalm and build tooling
This change introduces the primary \composer.json\ for the \vimeo/psalm\ project, establishing runtime dependencies on PHP 8.1–8.5 and libraries such as \nikic/php-parser\ ^5.2.0, \amphp/amp\ ^3, and \symfony/console\ ^6–^8. It also adds a separate \psalm/phar\ manifest for the PHAR distribution (requiring PHP ^8.2 and conflicting with \vimeo/psalm\), along with vendor-bin manifests for \humbug/box\ and \roave/backward-compatibility-check\, and example/test fixtures.
(dependencies) · high confidence
Housekeeping
Placeholder added for PHPUnit build directory
An empty .gitkeep file was added to the build/phpunit directory to ensure the directory is tracked in version control, likely in preparation for future PHPUnit configuration or build scripts.
build · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 67.
Lenses
- Code Health 74
- Architecture 99
- Maturity 62
- Readiness 66
- Security 72
Changes since last survey
- 300 commits — 202 feature/other, 98 fixes
By area
- src/Psalm — 125 commits
- (repo) — 74 commits
- .github/workflows — 17 commits
- (root) — 15 commits
- bin/ci — 9 commits
- bin/stubs — 7 commits
- dictionaries/autogen — 5 commits
- dictionaries/override — 5 commits
- tests/fixtures — 5 commits
- tests/LanguageServer — 4 commits
- docs/running_psalm — 3 commits
- tests/Internal — 3 commits
- bin/hack-conformance — 2 commits
- tests/Config — 2 commits
- tests/FileUpdates — 2 commits
- tests/MagicPropertyTest.php — 2 commits
- tests/Template — 2 commits
- dictionaries/CallMap_70.php — 1 commit
- dictionaries/CallMap_84.php — 1 commit
- dictionaries/CallMap_85.php — 1 commit
Notable commits
- fix: Add fix for PropertyHooks Fixes 11208
- fix: Attempt fix for windows
- fix: Cache fix
- fix: Final fixes
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- fix: Fix
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
vimeo/psalm was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 82c6021c0311b8473d02911cfa1ab6451dd665b2 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.