Description
Description
It would be convenient for contributors editing those files (run-tests.php, build/gen_stub.php, etc.) if static analyzer configs were set up (or used in CI) for editing files, to catch common mistakes such as undefined variables, unused variable declarations, type errors, etc.
It would also save time debugging/reviewing changes, e.g. #8023
https://github.com/vimeo/psalm
https://github.com/phan/phan
https://github.com/phpstan/phpstan
Documentation should probably make it clear that these are community projects separate from php itself, and there isn't an official static analyzer being endorsed?
(Note: I'm a maintainer of phan and have made a few contributions to psalm)
For CI purposes, bundling an exact phar version for predictable results would be ideal. psalm, phan, phpstan support methods of suppressing issues types in files (outside of the files themselves) such as baselines where pre-existing issues in files can be suppressed.
It's probably easiest to set up only one in CI to make fixing CI failures easier, but would be convenient to provide configs for other analyzers (even in a contrib/ folder or issue tracker) to use locally
E.g. this part of build/gen_stub.php
public function toVarEscapedName(): string {
$name = str_replace('_', '__', $this->name); // PhanUnusedVariable Unused definition of variable $name
return str_replace('\\', '_', $this->name);
}
<?php
use Phan\Issue;
/**
* This configuration will be read and overlayed on top of the
* default configuration. Command line arguments will be applied
* after this file is read.
* @see https://github.com/phan/phan/wiki/Phan-Config-Settings for all configurable options
* @see https://github.com/phan/phan
*/
return [
"use_polyfill_parser" => !extension_loaded('ast'),
"allow_missing_properties" => false,
"redundant_condition_detection" => true,
"minimum_target_php_version" => '7.4',
// If enabled, scalars (int, float, bool, string, null)
// are treated as if they can cast to each other.
'scalar_implicit_cast' => false,
// If true, seemingly undeclared variables in the global
// scope will be ignored. This is useful for projects
// with complicated cross-file globals that you have no
// hope of fixing.
'ignore_undeclared_variables_in_global_scope' => false,
// Backwards Compatibility Checking
'backward_compatibility_checks' => true,
'unused_variable_detection' => true,
// If true, check to make sure the return type declared
// in the doc-block (if any) matches the return type
// declared in the method signature.
'check_docblock_signature_return_type_match' => true,
// (*Requires check_docblock_signature_param_type_match to be true*)
// If true, make narrowed types from phpdoc params override
// the real types from the signature, when real types exist.
// (E.g. allows specifying desired lists of subclasses,
// or to indicate a preference for non-nullable types over nullable types)
// Affects analysis of the body of the method and the param types passed in by callers.
'prefer_narrowed_phpdoc_param_type' => true,
// (*Requires check_docblock_signature_return_type_match to be true*)
// If true, make narrowed types from phpdoc returns override
// the real types from the signature, when real types exist.
// (E.g. allows specifying desired lists of subclasses,
// or to indicate a preference for non-nullable types over nullable types)
// Affects analysis of return statements in the body of the method and the return types passed in by callers.
'prefer_narrowed_phpdoc_return_type' => true,
'ensure_signature_compatibility' => true,
'max_literal_string_type_length' => 1000,
// Set to true in order to attempt to detect dead
// (unreferenced) code. Keep in mind that the
// results will only be a guess given that classes,
// properties, constants and methods can be referenced
// as variables (like `$class->$property` or
// `$class->$method()`) in ways that we're unable
// to make sense of.
'dead_code_detection' => false,
// Run a quick version of checks that takes less
// time
"quick_mode" => false,
'simplify_ast' => true,
// Enable or disable support for generic templated
// class types.
'generic_types_enabled' => true,
'check_docblock_signature_return_type_match' => true,
// The minimum severity level to report on. This can be
// set to Issue::SEVERITY_LOW, Issue::SEVERITY_NORMAL or
// Issue::SEVERITY_CRITICAL.
'minimum_severity' => Issue::SEVERITY_LOW,
// Add any issue types (such as 'PhanUndeclaredMethod')
// here to inhibit them from being reported
'suppress_issue_types' => [
// 'PhanUndeclaredMethod',
],
// If empty, no filter against issues types will be applied.
// If non-empty, only issues within the list will be emitted
// by Phan.
'whitelist_issue_types' => [
],
// A list of files to include in analysis
'file_list' => [
'run-tests.php',
'pear/fetch.php',
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
'build',
'sapi',
'scripts/dev',
'ext',
'Zend',
],
// A file list that defines files that will be excluded
// from parsing and analysis and will not be read at all.
//
// This is useful for excluding hopelessly unanalyzable
// files that can't be removed for whatever reason.
'exclude_file_list' => [],
'exclude_file_regex' => '@(stub\.php$)|/tests/@',
// The number of processes to fork off during the analysis
// phase.
'processes' => 1,
// If enabled, warn about throw statement where the exception types
// are not documented in the PHPDoc of functions, methods, and closures.
// 'warn_about_undocumented_throw_statements' => true,
// A directory list that defines files that will be excluded
// from static analysis, but whose class and method
// information should be included.
//
// Generally, you'll want to include the directories for
// third-party code (such as "vendor/") in this list.
//
// n.b.: If you'd like to parse but not analyze 3rd
// party code, directories containing that code
// should be added to the `directory_list` as
// to `exclude_analysis_directory_list`.
"exclude_analysis_directory_list" => [
...glob('build/PHP-Parser-*'),
],
'enable_extended_internal_return_type_plugins' => true,
'plugin_config' => [
//'php_native_syntax_check_binaries' => ['php56'],
'php_native_syntax_check_max_processes' => 5
],
// A list of plugin files to execute
'plugins' => [
'AlwaysReturnPlugin',
'DollarDollarPlugin',
'UnreachableCodePlugin',
'DuplicateArrayKeyPlugin',
'PregRegexCheckerPlugin',
'PrintfCheckerPlugin',
'UseReturnValuePlugin',
// UnknownElementTypePlugin warns about unknown types in element signatures.
'UnknownElementTypePlugin',
'DuplicateExpressionPlugin',
// warns about carriage returns("\r"), trailing whitespace, and tabs in PHP files.
'WhitespacePlugin',
// Warn about inline HTML anywhere in the files.
'InlineHTMLPlugin',
// 'PossiblyStaticMethodPlugin',
// 'HasPHPDocPlugin',
// 'PHPDocToRealTypesPlugin', // suggests replacing (at)return void with `: void` in the declaration, etc.
'PHPDocRedundantPlugin',
'PreferNamespaceUsePlugin',
'EmptyStatementListPlugin',
// Report empty (not overridden or overriding) methods and functions
// 'EmptyMethodAndFunctionPlugin',
// Warn about using the same loop variable name as a loop variable of an outer loop.
'LoopVariableReusePlugin',
// Warn about assigning the value the variable already had to that variable.
'RedundantAssignmentPlugin',
// 'ShortArrayPlugin', Suggest replacing array() with []
'SimplifyExpressionPlugin',
],
'enable_internal_return_type_plugins' => true,
'enable_extended_internal_return_type_plugins' => true,
];