Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make callbacks marked as static #6695

Merged
merged 1 commit into from Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADING.md
Expand Up @@ -779,6 +779,8 @@
- [BC] Class `Psalm\Type\Atomic\TClassConstant` became final
- [BC] Class `Psalm\Type\TaintKind` became final
- [BC] Class `Psalm\Type\Union` became final
- [BC] Property `Psalm\Config::$universal_object_crates` changed default value
from `array{'stdClass','SimpleXMLElement','SimpleXMLIterator'}` to `null`

## Removed
- [BC] Property `Psalm\Codebase::$php_major_version` was removed, use
Expand Down
18 changes: 2 additions & 16 deletions psalm-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@485e516088a22efd18e902926a2efdad1b040d72">
<files psalm-version="dev-master@f7fc28bf5c23969ef1d9c8fd26f020ade0a2db9e">
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$comment_block-&gt;tags['variablesfrom'][0]</code>
Expand All @@ -17,9 +17,6 @@
<code>$matches[0]</code>
<code>$symbol_parts[1]</code>
</PossiblyUndefinedIntArrayOffset>
<PossiblyUnusedProperty occurrences="1">
<code>$analysis_php_version_id</code>
</PossiblyUnusedProperty>
</file>
<file src="src/Psalm/Config/FileFilter.php">
<PossiblyUndefinedIntArrayOffset occurrences="1">
Expand Down Expand Up @@ -70,11 +67,6 @@
<code>$traverser-&gt;traverse([$switch_condition])[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php">
<InvalidPropertyAssignmentValue occurrences="1">
<code>$catch_context-&gt;assigned_var_ids += $old_catch_assigned_var_ids</code>
</InvalidPropertyAssignmentValue>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php">
<PossiblyUndefinedIntArrayOffset occurrences="34">
<code>$assertion-&gt;rule[0]</code>
Expand Down Expand Up @@ -308,23 +300,17 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/TypeParser.php">
<PossiblyUndefinedIntArrayOffset occurrences="9">
<PossiblyUndefinedIntArrayOffset occurrences="8">
<code>$intersection_types[0]</code>
<code>$parse_tree-&gt;children[0]</code>
<code>$parse_tree-&gt;condition-&gt;children[0]</code>
<code>array_keys($offset_template_data)[0]</code>
<code>array_keys($template_type_map[$array_param_name])[0]</code>
<code>array_keys($template_type_map[$class_name])[0]</code>
<code>array_keys($template_type_map[$fq_classlike_name])[0]</code>
<code>array_keys($template_type_map[$param_name])[0]</code>
<code>array_keys($template_type_map[$template_param_name])[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Issue/MethodSignatureMustProvideReturnType.php">
<UnusedClass occurrences="1">
<code>MethodSignatureMustProvideReturnType</code>
</UnusedClass>
</file>
<file src="src/Psalm/Node/Stmt/VirtualClass.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualClass</code>
Expand Down
33 changes: 18 additions & 15 deletions src/Psalm/Config.php
Expand Up @@ -49,7 +49,6 @@
use stdClass;

use function array_key_exists;
use function array_map;
use function array_merge;
use function array_pad;
use function array_pop;
Expand Down Expand Up @@ -164,13 +163,9 @@ class Config

/**
* These are special object classes that allow any and all properties to be get/set on them
* @var array<int, class-string>
* @var array<int, lowercase-string>
*/
protected $universal_object_crates = [
stdClass::class,
SimpleXMLElement::class,
SimpleXMLIterator::class,
];
protected $universal_object_crates;
orklah marked this conversation as resolved.
Show resolved Hide resolved

/**
* @var static|null
Expand Down Expand Up @@ -619,6 +614,11 @@ protected function __construct()
{
self::$instance = $this;
$this->eventDispatcher = new EventDispatcher();
$this->universal_object_crates = [
strtolower(stdClass::class),
strtolower(SimpleXMLElement::class),
strtolower(SimpleXMLIterator::class),
];
}

/**
Expand Down Expand Up @@ -2227,7 +2227,7 @@ public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?P

if (file_exists($vendor_autoload_files_path)) {
$this->include_collector->runAndCollect(
fn(): array =>
static fn(): array =>
/**
* @psalm-suppress UnresolvableInclude
* @var string[]
Expand All @@ -2246,11 +2246,7 @@ public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?P
$codebase->classlikes->forgetMissingClassLikes();

$this->include_collector->runAndCollect(
function (): void {
// do this in a separate method so scope does not leak
/** @psalm-suppress UnresolvableInclude */
require $this->autoloader;
}
[$this, 'requireAutoloader']
orklah marked this conversation as resolved.
Show resolved Hide resolved
);
}

Expand Down Expand Up @@ -2438,14 +2434,21 @@ public function addUniversalObjectCrate(string $class): void
if (!class_exists($class)) {
throw new UnexpectedValueException($class . ' is not a known class');
}
$this->universal_object_crates[] = $class;
$this->universal_object_crates[] = strtolower($class);
}

/**
* @return array<int, lowercase-string>
*/
public function getUniversalObjectCrates(): array
{
return array_map('strtolower', $this->universal_object_crates);
return $this->universal_object_crates;
}

/** @internal */
public function requireAutoloader(): void
orklah marked this conversation as resolved.
Show resolved Hide resolved
{
/** @psalm-suppress UnresolvableInclude */
require $this->autoloader;
}
}
2 changes: 1 addition & 1 deletion src/Psalm/Config/Creator.php
Expand Up @@ -141,7 +141,7 @@ public static function getLevel(array $issues, int $counted_types): int
// remove any issues where < 0.1% of expressions are affected
$filtered_issues = array_filter(
$issues,
fn($amount): bool => $amount > 0.1
static fn($amount): bool => $amount > 0.1
);

if (array_sum($filtered_issues) > 0.5) {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Config/FileFilter.php
Expand Up @@ -434,7 +434,7 @@ public static function loadFromXMLElement(
private static function isRegularExpression(string $string): bool
{
set_error_handler(
fn(): bool => false,
static fn(): bool => false,
E_WARNING
);
$is_regexp = preg_match($string, '') !== false;
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Config/IssueHandler.php
Expand Up @@ -161,10 +161,10 @@ public static function getAllIssueTypes(): array
{
return array_filter(
array_map(
fn(string $file_name): string => substr($file_name, 0, -4),
static fn(string $file_name): string => substr($file_name, 0, -4),
scandir(dirname(__DIR__) . '/Issue', SCANDIR_SORT_NONE)
),
fn(string $issue_name): bool => $issue_name !== ''
static fn(string $issue_name): bool => $issue_name !== ''
&& $issue_name !== 'MethodIssue'
&& $issue_name !== 'PropertyIssue'
&& $issue_name !== 'ClassConstantIssue'
Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/ErrorBaseline.php
Expand Up @@ -48,7 +48,7 @@ public static function countTotalIssues(array $existingIssues): int
/**
* @param array{o:int, s:array<int, string>} $existingIssue
*/
fn(int $carry, array $existingIssue): int => $carry + $existingIssue['o'],
static fn(int $carry, array $existingIssue): int => $carry + $existingIssue['o'],
0
);
}
Expand Down Expand Up @@ -196,7 +196,7 @@ private static function countIssueTypesByFile(array $issues): array
*
* @return array<string,array<string,array{o:int, s:array<int, string>}>>
*/
function (array $carry, IssueData $issue): array {
static function (array $carry, IssueData $issue): array {
if ($issue->severity !== Config::REPORT_ERROR) {
return $carry;
}
Expand Down Expand Up @@ -258,7 +258,7 @@ private static function writeToFile(
('php:' . PHP_VERSION),
],
array_map(
fn(string $extension): string => $extension . ':' . phpversion($extension),
static fn(string $extension): string => $extension . ':' . phpversion($extension),
$extensions
)
)));
Expand Down Expand Up @@ -295,7 +295,7 @@ private static function writeToFile(
/**
* @param string[] $matches
*/
fn(array $matches): string => '<files' .
static fn(array $matches): string => '<files' .
"\n " .
$matches[1] .
"\n" .
Expand Down
55 changes: 26 additions & 29 deletions src/Psalm/Internal/Algebra.php
Expand Up @@ -10,10 +10,10 @@
use function array_filter;
use function array_intersect_key;
use function array_keys;
use function array_map;
use function array_merge;
use function array_pop;
use function array_values;
use function assert;
use function count;
use function in_array;
use function mt_rand;
Expand All @@ -33,39 +33,36 @@ class Algebra
*/
public static function negateTypes(array $all_types): array
{
return array_filter(
array_map(
/**
* @param non-empty-list<non-empty-list<Assertion>> $anded_types
*
* @return list<non-empty-list<Assertion>>
*/
function (array $anded_types): array {
if (count($anded_types) > 1) {
$new_anded_types = [];

foreach ($anded_types as $orred_types) {
if (count($orred_types) > 1) {
return [];
}
$negated_types = [];

$new_anded_types[] = $orred_types[0]->getNegation();
}
foreach ($all_types as $key => $anded_types) {
if (count($anded_types) > 1) {
$new_anded_types = [];

return [$new_anded_types];
foreach ($anded_types as $orred_types) {
if (count($orred_types) === 1) {
$new_anded_types[] = $orred_types[0]->getNegation();
} else {
continue 2;
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to debug errors:

ERROR: Trace - src/Psalm/Internal/Algebra.php:48:49 - $anded_types: non-empty-list<non-empty-list<Psalm\Storage\Assertion>> (see https://psalm.dev/224)
                /** @psalm-trace $anded_types */;


ERROR: Trace - src/Psalm/Internal/Algebra.php:49:53 - $new_anded_types: list<Psalm\Storage\Assertion> (see https://psalm.dev/224)
                /** @psalm-trace $new_anded_types */;

It looks like continue 2; is not properly handled by psalm here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have to take a closer look but I don't have much time these days. Can you add an assert($new_anded_types !== []); ? I think this should do the trick :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that helps. But that's excessive code (a performance waster) intended just to calm psalm. Tbh, adding this to baseline would be a bit better. I propose to wait a few days other suggestions :)

$new_orred_types = [];
assert($new_anded_types !== []);

foreach ($anded_types[0] as $orred_type) {
$new_orred_types[] = [$orred_type->getNegation()];
}
$negated_types[$key] = [$new_anded_types];
continue;
}

return $new_orred_types;
},
$all_types
)
);
$new_orred_types = [];

foreach ($anded_types[0] as $orred_type) {
$new_orred_types[] = [$orred_type->getNegation()];
}

$negated_types[$key] = $new_orred_types;
}

return $negated_types;
}

/**
Expand Down Expand Up @@ -654,7 +651,7 @@ public static function negateFormula(array $clauses): array
{
$clauses = array_filter(
$clauses,
fn($clause) => $clause->reconcilable
static fn(Clause $clause): bool => $clause->reconcilable
);

if (!$clauses) {
Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/Internal/Analyzer/ClassAnalyzer.php
Expand Up @@ -894,7 +894,7 @@ public static function addContextProperties(
if ($property_type_location && !$fleshed_out_type->isMixed()) {
$stmt = array_filter(
$stmts,
fn($stmt): bool => $stmt instanceof PhpParser\Node\Stmt\Property
static fn($stmt): bool => $stmt instanceof PhpParser\Node\Stmt\Property
&& isset($stmt->props[0]->name->name)
&& $stmt->props[0]->name->name === $property_name
);
Expand Down Expand Up @@ -1114,7 +1114,7 @@ private function checkPropertyInitialization(
$constructor_storage = $constructor_class_storage->methods['__construct'];

$fake_constructor_params = array_map(
function (FunctionLikeParameter $param): PhpParser\Node\Param {
static function (FunctionLikeParameter $param): PhpParser\Node\Param {
$fake_param = (new PhpParser\Builder\Param($param->name));
if ($param->signature_type) {
$fake_param->setType((string)$param->signature_type);
Expand All @@ -1138,7 +1138,7 @@ function (FunctionLikeParameter $param): PhpParser\Node\Param {
);

$fake_constructor_stmt_args = array_map(
function (FunctionLikeParameter $param): PhpParser\Node\Arg {
static function (FunctionLikeParameter $param): PhpParser\Node\Arg {
$attributes = $param->location
? [
'startFilePos' => $param->location->raw_file_start,
Expand Down Expand Up @@ -1943,7 +1943,7 @@ public static function analyzeClassMethodReturnType(
}

$overridden_method_ids = array_map(
fn($method_id) => $method_id->__toString(),
static fn($method_id): string => $method_id->__toString(),
$overridden_method_ids
);

Expand Down
21 changes: 9 additions & 12 deletions src/Psalm/Internal/Analyzer/ClosureAnalyzer.php
Expand Up @@ -16,7 +16,6 @@
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;

use function array_map;
use function in_array;
use function is_string;
use function preg_match;
Expand Down Expand Up @@ -231,17 +230,15 @@ public static function analyzeClosureUses(
PhpParser\Node\Expr\Closure $stmt,
Context $context
): ?bool {
$param_names = array_map(
function (PhpParser\Node\Param $p): string {
if (!$p->var instanceof PhpParser\Node\Expr\Variable
|| !is_string($p->var->name)
) {
return '';
}
return $p->var->name;
},
$stmt->params
);
$param_names = [];

foreach ($stmt->params as $i => $param) {
if ($param->var instanceof PhpParser\Node\Expr\Variable && is_string($param->var->name)) {
$param_names[$i] = $param->var->name;
} else {
$param_names[$i] = '';
}
}

foreach ($stmt->uses as $use) {
if (!is_string($use->var->name)) {
Expand Down
4 changes: 1 addition & 3 deletions src/Psalm/Internal/Analyzer/MethodComparator.php
Expand Up @@ -127,9 +127,7 @@ public static function compare(
&& !$implementer_method_storage->signature_return_type
&& !array_filter(
$implementer_method_storage->attributes,
function (AttributeStorage $s) {
return $s->fq_class_name === 'ReturnTypeWillChange';
}
static fn (AttributeStorage $s): bool => $s->fq_class_name === 'ReturnTypeWillChange'
)
) {
IssueBuffer::maybeAdd(
Expand Down