Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Oct 22, 2023
1 parent 71483b7 commit e8b7b30
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 100 deletions.
8 changes: 8 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@

- [BC] `Psalm\CodeLocation\Raw`, `Psalm\CodeLocation\ParseErrorLocation`, `Psalm\CodeLocation\DocblockTypeLocation`, `Psalm\Report\CountReport`, `Psalm\Type\Atomic\TNonEmptyArray` are now all final.

- [BC] `Psalm\Config` is now final.

- [BC] The return type of `Psalm\Plugin\ArgTypeInferer::infer` changed from `Union|false` to `Union|null`

- [BC] The `extra_types` property and `setIntersectionTypes` method of `Psalm\Type\Atomic\TTypeAlias` were removed.

- [BC] Methods `convertSeverity` and `calculateFingerprint` of `Psalm\Report\CodeClimateReport` were removed.

# Upgrading from Psalm 4 to Psalm 5
## Changed

Expand Down
43 changes: 22 additions & 21 deletions src/Psalm/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
use function flock;
use function fopen;
use function function_exists;
use function get_class;
use function get_defined_constants;
use function get_defined_functions;
use function getcwd;
Expand Down Expand Up @@ -98,7 +97,9 @@
use function scandir;
use function sha1;
use function simplexml_import_dom;
use function str_contains;
use function str_replace;
use function str_starts_with;
use function strlen;
use function strpos;
use function strrpos;
Expand Down Expand Up @@ -127,13 +128,13 @@
* @psalm-suppress PropertyNotSetInConstructor
* @psalm-consistent-constructor
*/
class Config
final class Config
{
private const DEFAULT_FILE_NAME = 'psalm.xml';
public const CONFIG_NAMESPACE = 'https://getpsalm.org/schema/config';
public const REPORT_INFO = 'info';
public const REPORT_ERROR = 'error';
public const REPORT_SUPPRESS = 'suppress';
final public const CONFIG_NAMESPACE = 'https://getpsalm.org/schema/config';
final public const REPORT_INFO = 'info';
final public const REPORT_ERROR = 'error';
final public const REPORT_SUPPRESS = 'suppress';

/**
* @var array<string>
Expand Down Expand Up @@ -172,7 +173,7 @@ class Config
*
* @var array<int, lowercase-string>
*/
protected array $universal_object_crates;
private array $universal_object_crates;

/**
* @var static|null
Expand Down Expand Up @@ -222,7 +223,7 @@ class Config

protected ?ProjectFileFilter $project_files = null;

protected ?ProjectFileFilter $extra_files = null;
private ?ProjectFileFilter $extra_files = null;

/**
* The base directory of this config file
Expand Down Expand Up @@ -426,7 +427,7 @@ class Config

private ?IncludeCollector $include_collector = null;

protected ?TaintAnalysisFileFilter $taint_analysis_ignored_files = null;
private ?TaintAnalysisFileFilter $taint_analysis_ignored_files = null;

/**
* @var bool whether to emit a backtrace of emitted issues to stderr
Expand Down Expand Up @@ -874,7 +875,6 @@ private static function processConfigDeprecations(
/**
* @param non-empty-string $file_contents
* @psalm-suppress MixedAssignment
* @psalm-suppress MixedArgument
* @psalm-suppress MixedPropertyFetch
* @throws ConfigException
*/
Expand Down Expand Up @@ -963,15 +963,15 @@ private static function fromXmlAndPaths(
if (file_exists($composer_json_path)) {
$composer_json_contents = file_get_contents($composer_json_path);
assert($composer_json_contents !== false);
$composer_json = json_decode($composer_json_contents, true);
$composer_json = json_decode($composer_json_contents, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($composer_json)) {
throw new UnexpectedValueException('Invalid composer.json at ' . $composer_json_path);
}
}
$required_extensions = [];
foreach (($composer_json["require"] ?? []) as $required => $_) {
if (strpos($required, "ext-") === 0) {
$required_extensions[strtolower(substr($required, 4))] = true;
if (str_starts_with((string) $required, "ext-")) {
$required_extensions[strtolower(substr((string) $required, 4))] = true;
}
}
foreach ($required_extensions as $required_ext => $_) {
Expand Down Expand Up @@ -1649,7 +1649,7 @@ public function reportIssueInFile(string $issue_type, string $file_path): bool
try {
$file_storage = $codebase->file_storage_provider->get($file_path);
$dependent_files += $file_storage->required_by_file_paths;
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException) {
// do nothing
}
}
Expand Down Expand Up @@ -1700,7 +1700,7 @@ public function trackTaintsInPath(string $file_path): bool

public function getReportingLevelForIssue(CodeIssue $e): string
{
$fqcn_parts = explode('\\', get_class($e));
$fqcn_parts = explode('\\', $e::class);
$issue_type = array_pop($fqcn_parts);

$reporting_level = null;
Expand Down Expand Up @@ -1765,17 +1765,17 @@ public static function getParentIssueType(string $issue_type): ?string
return null;
}

if (strpos($issue_type, 'Possibly') === 0) {
if (str_starts_with($issue_type, 'Possibly')) {
$stripped_issue_type = (string) preg_replace('/^Possibly(False|Null)?/', '', $issue_type, 1);

if (strpos($stripped_issue_type, 'Invalid') === false && strpos($stripped_issue_type, 'Un') !== 0) {
if (!str_contains($stripped_issue_type, 'Invalid') && !str_starts_with($stripped_issue_type, 'Un')) {
$stripped_issue_type = 'Invalid' . $stripped_issue_type;
}

return $stripped_issue_type;
}

if (strpos($issue_type, 'Tainted') === 0) {
if (str_starts_with($issue_type, 'Tainted')) {
return 'TaintedInput';
}

Expand Down Expand Up @@ -2298,7 +2298,7 @@ public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?P
$codebase->classlikes->forgetMissingClassLikes();

$this->include_collector->runAndCollect(
[$this, 'requireAutoloader'],
$this->requireAutoloader(...),
);
}

Expand All @@ -2324,7 +2324,8 @@ public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?P
}
}

public function getComposerFilePathForClassLike(string $fq_classlike_name): string|false
/** @return string|false */
public function getComposerFilePathForClassLike(string $fq_classlike_name): string|bool
{
if (!$this->composer_class_loader) {
return false;
Expand Down Expand Up @@ -2502,7 +2503,7 @@ public function getPHPVersionFromComposerJson(): ?string
$composer_json_contents = file_get_contents($composer_json_path);
assert($composer_json_contents !== false);
$composer_json = json_decode($composer_json_contents, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
} catch (JsonException) {
$composer_json = null;
}

Expand Down
15 changes: 6 additions & 9 deletions src/Psalm/Plugin/ArgTypeInferer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,16 @@

final class ArgTypeInferer
{
private Context $context;
private StatementsAnalyzer $statements_analyzer;

/**
* @internal
*/
public function __construct(Context $context, StatementsAnalyzer $statements_analyzer)
{
$this->context = $context;
$this->statements_analyzer = $statements_analyzer;
public function __construct(
private readonly Context $context,
private readonly StatementsAnalyzer $statements_analyzer,
) {
}

public function infer(PhpParser\Node\Arg $arg): false|Union
public function infer(PhpParser\Node\Arg $arg): null|Union
{
$already_inferred_type = $this->statements_analyzer->node_data->getType($arg->value);

Expand All @@ -34,7 +31,7 @@ public function infer(PhpParser\Node\Arg $arg): false|Union
}

if (ExpressionAnalyzer::analyze($this->statements_analyzer, $arg->value, $this->context) === false) {
return false;
return null;
}

return $this->statements_analyzer->node_data->getType($arg->value) ?? Type::getMixed();
Expand Down
6 changes: 3 additions & 3 deletions src/Psalm/Report/CodeClimateReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function create(): string
$options = $this->pretty ? Json::PRETTY : Json::DEFAULT;

$issues_data = array_map(
[$this, 'mapToNewStructure'],
$this->mapToNewStructure(...),
$this->issues_data,
);

Expand All @@ -39,7 +39,7 @@ public function create(): string
* convert our own severity to CodeClimate format
* Values can be : info, minor, major, critical, or blocker
*/
protected function convertSeverity(string $input): string
private function convertSeverity(string $input): string
{
if (Config::REPORT_INFO === $input) {
return 'info';
Expand All @@ -58,7 +58,7 @@ protected function convertSeverity(string $input): string
/**
* calculate a unique fingerprint for a given issue
*/
protected function calculateFingerprint(IssueData $issue): string
private function calculateFingerprint(IssueData $issue): string
{
return md5($issue->type.$issue->message.$issue->file_name.$issue->from.$issue->to);
}
Expand Down
57 changes: 4 additions & 53 deletions src/Psalm/Type/Atomic/TTypeAlias.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,17 @@

use Psalm\Type\Atomic;

use function array_map;
use function implode;

/**
* @psalm-immutable
*/
final class TTypeAlias extends Atomic
{
/**
* @var array<string, TTypeAlias>|null
* @deprecated type aliases are resolved within {@see TypeParser::resolveTypeAliases()} and therefore the
* referencing type(s) are part of other intersection types. The intersection types are not set anymore
* and with v6 this property along with its related methods will get removed.
*/
public ?array $extra_types = null;

public string $declaring_fq_classlike_name;

public string $alias_name;

/**
* @param array<string, TTypeAlias>|null $extra_types
*/
public function __construct(string $declaring_fq_classlike_name, string $alias_name, ?array $extra_types = null)
{
$this->declaring_fq_classlike_name = $declaring_fq_classlike_name;
$this->alias_name = $alias_name;
/** @psalm-suppress DeprecatedProperty For backwards compatibility, we have to keep this here. */
$this->extra_types = $extra_types;
public function __construct(
public string $declaring_fq_classlike_name,
public string $alias_name,
) {
parent::__construct(true);
}
/**
* @param array<string, TTypeAlias>|null $extra_types
* @deprecated type aliases are resolved within {@see TypeParser::resolveTypeAliases()} and therefore the
* referencing type(s) are part of other intersection types. This method will get removed with v6.
* @psalm-suppress PossiblyUnusedMethod For backwards compatibility, we have to keep this here.
*/
public function setIntersectionTypes(?array $extra_types): self
{
/** @psalm-suppress DeprecatedProperty For backwards compatibility, we have to keep this here. */
if ($extra_types === $this->extra_types) {
return $this;
}
return new self(
$this->declaring_fq_classlike_name,
$this->alias_name,
$extra_types,
);
}

public function getKey(bool $include_extra = true): string
{
Expand All @@ -63,17 +25,6 @@ public function getKey(bool $include_extra = true): string

public function getId(bool $exact = true, bool $nested = false): string
{
/** @psalm-suppress DeprecatedProperty For backwards compatibility, we have to keep this here. */
if ($this->extra_types) {
return $this->getKey() . '&' . implode(
'&',
array_map(
static fn(Atomic $type): string => $type->getId($exact, true),
$this->extra_types,
),
);
}

return $this->getKey();
}

Expand Down
2 changes: 1 addition & 1 deletion tests/EnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ function noop(string $s): string
$foo = FooEnum::Foo->value;
noop($foo);
noop(FooEnum::Foo->value);
PHP,
PHP,
'assertions' => [],
'ignored_issues' => [],
'php_version' => '8.1',
Expand Down
4 changes: 2 additions & 2 deletions tests/PsalmPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class PsalmPluginTest extends TestCase
{
use MockeryPHPUnitIntegration;

private PluginList&MockInterface $plugin_list;
private MockInterface $plugin_list;

private PluginListFactory&MockInterface $plugin_list_factory;
private MockInterface $plugin_list_factory;

private Application $app;

Expand Down
Loading

0 comments on commit e8b7b30

Please sign in to comment.