Skip to content

Commit 8af3c1c

Browse files
committed
psalm est mort, vive le phpstan!
1 parent b2720ea commit 8af3c1c

13 files changed

+47
-145
lines changed

Diff for: composer.json

+9-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
},
1919
"require-dev": {
2020
"friendsofphp/php-cs-fixer": "^3.53",
21+
"phpstan/extension-installer": "^1.3",
22+
"phpstan/phpstan": "^1.10",
23+
"phpstan/phpstan-strict-rules": "^1.5",
2124
"phpunit/phpunit": "^10.5",
2225
"rector/rector": "^1.0",
23-
"type-lang/parser": "^1.0",
24-
"vimeo/psalm": "^5.23"
26+
"type-lang/parser": "^1.0"
2527
},
2628
"autoload-dev": {
2729
"psr-4": {
@@ -41,6 +43,9 @@
4143
"optimize-autoloader": true,
4244
"preferred-install": {
4345
"*": "dist"
46+
},
47+
"allow-plugins": {
48+
"phpstan/extension-installer": true
4449
}
4550
},
4651
"scripts": {
@@ -49,8 +54,8 @@
4954
"test:functional": "phpunit --testsuite=functional",
5055

5156
"linter": "@linter:check",
52-
"linter:check": "psalm --no-cache",
53-
"linter:fix": "psalm --no-cache --alter",
57+
"linter:check": "phpstan analyse --configuration phpstan.neon",
58+
"linter:baseline": "phpstan analyse --configuration phpstan.neon --generate-baseline",
5459

5560
"phpcs": "@phpcs:check",
5661
"phpcs:check": "php-cs-fixer fix --config=.php-cs-fixer.php --allow-risky=yes --dry-run --verbose --diff",

Diff for: phpstan.neon

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
includes:
2+
- phar://phpstan.phar/conf/bleedingEdge.neon
3+
parameters:
4+
level: 9
5+
strictRules:
6+
allRules: true
7+
fileExtensions:
8+
- php
9+
paths:
10+
- src
11+
tmpDir: vendor/.cache.phpstan
12+
reportUnmatchedIgnoredErrors: false

Diff for: psalm.xml

-37
This file was deleted.

Diff for: src/DocBlock.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* This class represents structure containing a description and a set of tags
1515
* that describe an arbitrary DocBlock Comment in the code.
1616
*
17-
* @template-implements \ArrayAccess<int<0, max>, TagInterface|null>
18-
* @template-implements \IteratorAggregate<int<0, max>, TagInterface>
17+
* @template-implements \ArrayAccess<array-key, TagInterface|null>
18+
* @template-implements \IteratorAggregate<array-key, TagInterface>
1919
*/
2020
final class DocBlock implements
2121
OptionalDescriptionProviderInterface,
@@ -28,7 +28,6 @@ final class DocBlock implements
2828

2929
/**
3030
* @var list<TagInterface>
31-
* @psalm-suppress PropertyNotSetInConstructor
3231
*/
3332
private readonly array $tags;
3433

@@ -54,6 +53,9 @@ public function getDescription(): DescriptionInterface
5453
return $this->description;
5554
}
5655

56+
/**
57+
* @return list<TagInterface>
58+
*/
5759
public function getTags(): array
5860
{
5961
return $this->tags;

Diff for: src/Parser/Description/RegexDescriptionParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private function getDocBlockChunks(string $contents): array
9191
}
9292

9393
/** @var list<non-empty-string> */
94-
return \array_filter($result);
94+
return \array_filter($result, static fn (string $chunk): bool => $chunk !== '');
9595
}
9696

9797
/**

Diff for: src/Parser/Tag/RegexTagParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ public function parse(string $tag, DescriptionParserInterface $parser): TagInter
8585
try {
8686
return $this->tags->create($name, new Content($trimmed), $parser);
8787
} catch (RuntimeExceptionInterface $e) {
88-
/** @var int<0, max> */
8988
$offset += \strlen($content) - \strlen($trimmed);
9089

90+
/** @var int<0, max> $offset */
9191
throw $e->withSource($tag, $offset);
9292
}
9393
}

Diff for: src/Tag/Content.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function shift(int $offset, bool $ltrim = true): void
5050
$this->value = \ltrim($this->value);
5151
}
5252

53-
/** @psalm-suppress InvalidPropertyAssignmentValue */
53+
// @phpstan-ignore-next-line : Offset already greater than 0
5454
$this->offset += $size - \strlen($this->value);
5555
}
5656

@@ -175,6 +175,15 @@ public function toDescription(DescriptionParserInterface $descriptions): Descrip
175175
return $descriptions->parse($this->value);
176176
}
177177

178+
public function toOptionalDescription(DescriptionParserInterface $descriptions): ?DescriptionInterface
179+
{
180+
if (\trim($this->value) === '') {
181+
return null;
182+
}
183+
184+
return $descriptions->parse(\rtrim($this->value));
185+
}
186+
178187
public function __toString(): string
179188
{
180189
return $this->value;

Diff for: src/Tag/Content/OptionalTypeParserApplicator.php

+1-7
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
*/
1616
final class OptionalTypeParserApplicator extends Applicator
1717
{
18-
/**
19-
* @param non-empty-string $tag
20-
*/
2118
public function __construct(
2219
private readonly TypesParserInterface $parser,
2320
) {}
@@ -36,10 +33,7 @@ public function __invoke(Content $lexer): ?TypeStatement
3633
return null;
3734
}
3835

39-
/**
40-
* @psalm-suppress MixedArgument
41-
* @psalm-suppress NoInterfaceProperties
42-
*/
36+
// @phpstan-ignore-next-line : Property is defined
4337
$lexer->shift($this->parser->lastProcessedTokenOffset);
4438

4539
return $type;

Diff for: src/Tag/Content/TypeParserApplicator.php

+1-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public function __construct(
3232
public function __invoke(Content $lexer): TypeStatement
3333
{
3434
try {
35-
/** @var TypeStatement $type */
3635
$type = $this->parser->parse($lexer->value);
3736
} catch (ParserExceptionInterface $e) {
3837
/** @psalm-suppress InvalidArgument */
@@ -42,10 +41,7 @@ public function __invoke(Content $lexer): TypeStatement
4241
);
4342
}
4443

45-
/**
46-
* @psalm-suppress MixedArgument
47-
* @psalm-suppress NoInterfaceProperties
48-
*/
44+
// @phpstan-ignore-next-line : Property is defined
4945
$lexer->shift($this->parser->lastProcessedTokenOffset);
5046

5147
return $type;

Diff for: src/Tag/Content/ValueApplicator.php

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
*/
1414
final class ValueApplicator extends Applicator
1515
{
16+
/**
17+
* @var OptionalValueApplicator<T>
18+
*/
1619
private readonly OptionalValueApplicator $identifier;
1720

1821
/**

Diff for: src/Tag/Description/TaggedDescription.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use TypeLang\PHPDoc\Tag\TagInterface;
88

99
/**
10-
* @template-implements \ArrayAccess<int<0, max>, TagInterface|DescriptionInterface|null>
11-
* @template-implements \IteratorAggregate<int<0, max>, TagInterface|DescriptionInterface>
10+
* @template-implements \ArrayAccess<array-key, TagInterface|DescriptionInterface|null>
11+
* @template-implements \IteratorAggregate<array-key, TagInterface|DescriptionInterface>
1212
*/
1313
class TaggedDescription implements
1414
TaggedDescriptionInterface,
@@ -60,7 +60,7 @@ public function count(): int
6060

6161
public function offsetExists(mixed $offset): bool
6262
{
63-
return isset($this->tags[$offset]);
63+
return isset($this->components[$offset]);
6464
}
6565

6666
public function offsetGet(mixed $offset): TagInterface|DescriptionInterface|null

Diff for: src/Tag/Description/TaggedDescriptionInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* containing an arbitrary set of nested tags ({@see TagInterface}) and,
1313
* like a parent {@see DescriptionInterface}, can be represented as a string.
1414
*
15-
* @template-extends \Traversable<int<0, max>, DescriptionInterface|TagInterface>
15+
* @template-extends \Traversable<array-key, DescriptionInterface|TagInterface>
1616
*/
1717
interface TaggedDescriptionInterface extends
1818
TagsProviderInterface,

Diff for: src/Tag/TagsProvider.php

-82
This file was deleted.

0 commit comments

Comments
 (0)