Skip to content

Commit

Permalink
InvalidPhpDocTagValueRule - backward compatibility of the error messa…
Browse files Browse the repository at this point in the history
…ge without bleedingEdge
  • Loading branch information
ondrejmirtes committed May 9, 2023
1 parent 74d1c9a commit a04e0be
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 4 deletions.
1 change: 1 addition & 0 deletions conf/bleedingEdge.neon
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ parameters:
propertyVariance: true
genericPrototypeMessage: true
stricterFunctionMap: true
invalidPhpDocTagLine: true
1 change: 1 addition & 0 deletions conf/config.level2.neon
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ services:
class: PHPStan\Rules\PhpDoc\InvalidPhpDocTagValueRule
arguments:
checkAllInvalidPhpDocs: %featureToggles.allInvalidPhpDocs%
invalidPhpDocTagLine: %featureToggles.invalidPhpDocTagLine%
tags:
- phpstan.rules.rule
-
Expand Down
2 changes: 2 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ parameters:
propertyVariance: false
genericPrototypeMessage: false
stricterFunctionMap: false
invalidPhpDocTagLine: false
fileExtensions:
- php
checkAdvancedIsset: false
Expand Down Expand Up @@ -304,6 +305,7 @@ parametersSchema:
propertyVariance: bool()
genericPrototypeMessage: bool()
stricterFunctionMap: bool()
invalidPhpDocTagLine: bool()
])
fileExtensions: listOf(string())
checkAdvancedIsset: bool()
Expand Down
1 change: 1 addition & 0 deletions src/PhpDoc/StubValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ private function getRuleRegistry(Container $container): RuleRegistry
$container->getByType(Lexer::class),
$container->getByType(PhpDocParser::class),
$container->getParameter('featureToggles')['allInvalidPhpDocs'],
$container->getParameter('featureToggles')['invalidPhpDocTagLine'],
),
new InvalidThrowsPhpDocValueRule($fileTypeMapper),

Expand Down
15 changes: 13 additions & 2 deletions src/Rules/PhpDoc/InvalidPhpDocTagValueRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PHPStan\Rules\PhpDoc;

use Nette\Utils\Strings;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\VirtualNode;
Expand All @@ -26,6 +27,7 @@ public function __construct(
private Lexer $phpDocLexer,
private PhpDocParser $phpDocParser,
private bool $checkAllInvalidPhpDocs,
private bool $invalidPhpDocTagLine,
)
{
}
Expand Down Expand Up @@ -86,7 +88,7 @@ public function processNode(Node $node, Scope $scope): array
'PHPDoc tag %s %s has invalid value: %s',
$phpDocTag->name,
$phpDocTag->value->alias,
$phpDocTag->value->type->getException()->getMessage(),
$this->trimExceptionMessage($phpDocTag->value->type->getException()->getMessage()),
))->build();

continue;
Expand All @@ -98,11 +100,20 @@ public function processNode(Node $node, Scope $scope): array
'PHPDoc tag %s has invalid value (%s): %s',
$phpDocTag->name,
$phpDocTag->value->value,
$phpDocTag->value->exception->getMessage(),
$this->trimExceptionMessage($phpDocTag->value->exception->getMessage()),
))->build();
}

return $errors;
}

private function trimExceptionMessage(string $message): string
{
if ($this->invalidPhpDocTagLine) {
return $message;
}

return Strings::replace($message, '~( on line \d+)$~', '');
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ parameters:
path: WindowsNewlines.php

-
message: "#^PHPDoc tag @param has invalid value \\(\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected type at offset 113 on line 4$#"
message: "#^PHPDoc tag @param has invalid value \\(\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected type at offset 113$#"
count: 1
path: WindowsNewlines.php

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ parameters:
path: UnixNewlines.php

-
message: "#^PHPDoc tag @param has invalid value \\(\\)\\: Unexpected token \"\\\\r\\\\n\\\\t \\* \", expected type at offset 110 on line 4$#"
message: "#^PHPDoc tag @param has invalid value \\(\\)\\: Unexpected token \"\\\\r\\\\n\\\\t \\* \", expected type at offset 110$#"
count: 1
path: UnixNewlines.php

Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\PhpDoc;

use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use function array_merge;

/**
* @extends RuleTestCase<InvalidPhpDocTagValueRule>
*/
class InvalidPhpDocTagValueRuleNoBleedingEdgeTest extends RuleTestCase
{

private bool $checkAllInvalidPhpDocs;

protected function getRule(): Rule
{
return new InvalidPhpDocTagValueRule(
self::getContainer()->getByType(Lexer::class),
self::getContainer()->getByType(PhpDocParser::class),
$this->checkAllInvalidPhpDocs,
false,
);
}

public function dataRule(): iterable
{
$errors = [
[
'PHPDoc tag @param has invalid value (): Unexpected token "\n * ", expected type at offset 13',
25,
],
[
'PHPDoc tag @param has invalid value (A & B | C $paramNameA): Unexpected token "|", expected variable at offset 72',
25,
],
[
'PHPDoc tag @param has invalid value ((A & B $paramNameB): Unexpected token "$paramNameB", expected \')\' at offset 105',
25,
],
[
'PHPDoc tag @param has invalid value (~A & B $paramNameC): Unexpected token "~A", expected type at offset 127',
25,
],
[
'PHPDoc tag @var has invalid value (): Unexpected token "\n * ", expected type at offset 156',
25,
],
[
'PHPDoc tag @var has invalid value ($invalid): Unexpected token "$invalid", expected type at offset 165',
25,
],
[
'PHPDoc tag @var has invalid value ($invalid Foo): Unexpected token "$invalid", expected type at offset 182',
25,
],
[
'PHPDoc tag @return has invalid value (): Unexpected token "\n * ", expected type at offset 208',
25,
],
[
'PHPDoc tag @return has invalid value ([int, string]): Unexpected token "[", expected type at offset 220',
25,
],
[
'PHPDoc tag @return has invalid value (A & B | C): Unexpected token "|", expected TOKEN_OTHER at offset 251',
25,
],
[
'PHPDoc tag @var has invalid value (\\\Foo|\Bar $test): Unexpected token "\\\\\\\Foo|\\\Bar", expected type at offset 9',
29,
],
[
'PHPDoc tag @var has invalid value ((Foo|Bar): Unexpected token "*/", expected \')\' at offset 18',
62,
],
[
'PHPDoc tag @throws has invalid value ((\Exception): Unexpected token "*/", expected \')\' at offset 24',
72,
],
[
'PHPDoc tag @var has invalid value ((Foo|Bar): Unexpected token "*/", expected \')\' at offset 18',
81,
],
[
'PHPDoc tag @var has invalid value ((Foo&): Unexpected token "*/", expected type at offset 15',
89,
],
[
'PHPDoc tag @var has invalid value ((Foo&): Unexpected token "*/", expected type at offset 15',
92,
],
];

yield [false, $errors];
yield [true, array_merge($errors, [
[
'PHPDoc tag @var has invalid value ((Foo&): Unexpected token "*/", expected type at offset 15',
102,
],
])];
}

/**
* @dataProvider dataRule
* @param list<array{0: string, 1: int, 2?: string}> $expectedErrors
*/
public function testRule(bool $checkAllInvalidPhpDocs, array $expectedErrors): void
{
$this->checkAllInvalidPhpDocs = $checkAllInvalidPhpDocs;
$this->analyse([__DIR__ . '/data/invalid-phpdoc.php'], $expectedErrors);
}

public function testBug4731(): void
{
$this->checkAllInvalidPhpDocs = true;
$this->analyse([__DIR__ . '/data/bug-4731.php'], []);
}

public function testBug4731WithoutFirstTag(): void
{
$this->checkAllInvalidPhpDocs = true;
$this->analyse([__DIR__ . '/data/bug-4731-no-first-tag.php'], []);
}

public function testInvalidTypeInTypeAlias(): void
{
$this->checkAllInvalidPhpDocs = true;
$this->analyse([__DIR__ . '/data/invalid-type-type-alias.php'], [
[
'PHPDoc tag @phpstan-type InvalidFoo has invalid value: Unexpected token "{", expected TOKEN_PHPDOC_EOL at offset 65',
12,
],
]);
}

public static function getAdditionalConfigFiles(): array
{
// reset bleedingEdge
return [];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ protected function getRule(): Rule
self::getContainer()->getByType(Lexer::class),
self::getContainer()->getByType(PhpDocParser::class),
$this->checkAllInvalidPhpDocs,
true,
);
}

Expand Down

0 comments on commit a04e0be

Please sign in to comment.