Skip to content

Commit dd1f30d

Browse files
Compatibility fixes for new versions of PHPStan and Nette
1 parent 280e5cb commit dd1f30d

File tree

12 files changed

+73
-48
lines changed

12 files changed

+73
-48
lines changed

phpstan.neon

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ parameters:
7272
path: src/Compiler/Compiler/AbstractCompiler.php
7373

7474
-
75-
message: '#^Parameter \#1 \$value of static method PhpParser\\BuilderHelpers\:\:normalizeValue\(\) expects array\|bool\|float\|int\|PhpParser\\Node\\Expr\|string\|null, mixed given\.$#'
75+
message: '#^Parameter \#1 \$value of static method PhpParser\\BuilderHelpers\:\:normalizeValue\(\) expects array\|bool\|float\|int\|PhpParser\\Node\\Expr\|string\|UnitEnum\|null, mixed given\.$#'
7676
path: src/LinkProcessor/LinkParamsProcessor.php
7777
-
7878
messages:
@@ -145,16 +145,6 @@ parameters:
145145
- '#^Although PHPStan\\Node\\InClassNode is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
146146
- '#^Although PHPStan\\Node\\ClassMethod is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
147147

148-
-
149-
messages:
150-
-'#^Although PHPStan\\Rules\\MetadataRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
151-
-'#^Although PHPStan\\Rules\\FileRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
152-
-'#^Although PHPStan\\Rules\\LineRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
153-
-'#^Although PHPStan\\Rules\\TipRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
154-
-'#^Although PHPStan\\Rules\\IdentifierRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
155-
-'#^Although PHPStan\\Rules\\NonIgnorableRuleError is covered by backward compatibility promise, this instanceof assumption might break because it''s not guaranteed to always stay the same\.$#'
156-
path: src/Error/ErrorBuilder.php
157-
158148
# to be done later, no idea how to fix it now
159149
-
160150
message: '#^Method Efabrica\\PHPStanLatte\\Collector\\Collector\\AbstractCollector::collectItems\(\) should return array\<A of array\>\|null but returns array\<int, array\<string, mixed\>\>\.$#'

src/Analyser/LatteContextAnalyser.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ public function analyseFile(string $file): LatteContextData
104104
try {
105105
$collectedData = $collector->collectData($node, $scope);
106106
} catch (Throwable $e) {
107-
$fileErrors[] = RuleErrorBuilder::message(get_class($collector) . ' error: ' . $e->getMessage())->file($file)->line($node->getLine())->build();
107+
$fileErrors[] = RuleErrorBuilder::message(get_class($collector) . ' error: ' . $e->getMessage())
108+
->identifier('latte.collectorError')
109+
->file($file)
110+
->line($node->getLine())
111+
->build();
108112
continue;
109113
}
110114
if ($collectedData === null || $collectedData === []) {
@@ -116,12 +120,21 @@ public function analyseFile(string $file): LatteContextData
116120
$scope = $this->scopeFactory->create(ScopeContext::create($file));
117121
$this->nodeScopeResolver->processNodes($parserNodes, $scope, $nodeCallback);
118122
} catch (Throwable $e) {
119-
$fileErrors[] = RuleErrorBuilder::message('LatteContextAnalyser error: ' . $e->getMessage())->file($file)->build();
123+
$fileErrors[] = RuleErrorBuilder::message('LatteContextAnalyser error: ' . $e->getMessage())
124+
->identifier('latte.failed')
125+
->file($file)
126+
->build();
120127
}
121128
} elseif (is_dir($file)) {
122-
$fileErrors[] = RuleErrorBuilder::message(sprintf('File %s is a directory.', $file))->file($file)->build();
129+
$fileErrors[] = RuleErrorBuilder::message(sprintf('File %s is a directory.', $file))
130+
->identifier('latte.fileError')
131+
->file($file)
132+
->build();
123133
} else {
124-
$fileErrors[] = RuleErrorBuilder::message(sprintf('File %s does not exist.', $file))->file($file)->build();
134+
$fileErrors[] = RuleErrorBuilder::message(sprintf('File %s does not exist.', $file))
135+
->identifier('latte.fileError')
136+
->file($file)
137+
->build();
125138
}
126139
return new LatteContextData($fileCollectedData, $fileErrors);
127140
}

src/Analyser/LatteContextData.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
use Efabrica\PHPStanLatte\LatteContext\CollectedData\CollectedError;
88
use Efabrica\PHPStanLatte\LatteContext\CollectedData\CollectedLatteContextObject;
9-
use PHPStan\Rules\RuleError;
9+
use PHPStan\Rules\IdentifierRuleError;
1010
use PHPStan\Rules\RuleErrorBuilder;
1111

1212
final class LatteContextData
1313
{
14-
/** @var array<RuleError> */
14+
/** @var list<IdentifierRuleError> */
1515
private array $errors;
1616

1717
/** @var array<CollectedLatteContextObject> */
@@ -22,7 +22,7 @@ final class LatteContextData
2222

2323
/**
2424
* @param array<CollectedLatteContextObject> $collectedData
25-
* @param array<RuleError> $errors
25+
* @param list<IdentifierRuleError> $errors
2626
*/
2727
public function __construct(array $collectedData, array $errors)
2828
{
@@ -34,21 +34,25 @@ public function __construct(array $collectedData, array $errors)
3434
}
3535

3636
/**
37-
* @return array<RuleError>
37+
* @return list<IdentifierRuleError>
3838
*/
3939
public function getErrors(): array
4040
{
4141
return $this->errors;
4242
}
4343

4444
/**
45-
* @return array<RuleError>
45+
* @return list<IdentifierRuleError>
4646
*/
4747
public function getCollectedErrors(): array
4848
{
4949
$errors = [];
5050
foreach ($this->getCollectedData(CollectedError::class) as $collectedError) {
51-
$errors[] = RuleErrorBuilder::message($collectedError->getMessage())->file($collectedError->getFile())->line($collectedError->getLine() ?? -1)->build();
51+
$errors[] = RuleErrorBuilder::message($collectedError->getMessage())
52+
->identifier('latte.error')
53+
->file($collectedError->getFile())
54+
->line($collectedError->getLine() ?? -1)
55+
->build();
5256
}
5357
return $errors;
5458
}

src/Compiler/NodeVisitor/AddParametersForBlockNodeVisitor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function leaveNode(Node $node): ?array
5858
$parameters = [];
5959
$pattern = '/(?<define>{define\s+(?<block_name>.*?)\s*,?\s+(?<parameters>.*)})\s+on line (?<line>\d+)/s';
6060
preg_match($pattern, $comment->getText(), $match);
61-
if (isset($match['parameters'])) {
61+
if (isset($match['define']) && isset($match['block_name']) &&isset($match['parameters'])) {
6262
$define = $match['define'];
6363

6464
$typesAndVariablesPattern = '/(?<type>[\?\\\[\]\<\>[:alnum:]]*)[ ]*\$(?<variable>[[:alnum:]]+)/s';

src/Error/ErrorBuilder.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use PHPStan\Rules\LineRuleError;
1616
use PHPStan\Rules\MetadataRuleError;
1717
use PHPStan\Rules\NonIgnorableRuleError;
18-
use PHPStan\Rules\RuleError;
1918
use PHPStan\Rules\RuleErrorBuilder;
2019
use PHPStan\Rules\TipRuleError;
2120

@@ -52,6 +51,8 @@ final class ErrorBuilder
5251
'/PHPDoc tag @var for variable \$__variables__ has no value type specified in iterable type array\./', // fake variable $__variables__ can have not specified array type
5352
'/Cannot call method startTag\(\) on Nette\\\\Utils\\\\Html\|string\./', // nette/forms error https://github.com/nette/forms/issues/308
5453
'/Cannot call method endTag\(\) on Nette\\\\Utils\\\\Html\|string\./', // nette/forms error https://github.com/nette/forms/issues/308
54+
'/Variable .* on left side of \?\?= is never defined./',
55+
'/Variable .* on left side of \?\?= always exists and is not nullable./',
5556
];
5657

5758
/** @var string[] */
@@ -89,7 +90,7 @@ public function __construct(
8990

9091
/**
9192
* @param Error[] $originalErrors
92-
* @return RuleError[]
93+
* @return IdentifierRuleError[]
9394
*/
9495
public function buildErrors(array $originalErrors, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): array
9596
{
@@ -110,7 +111,7 @@ public function buildErrors(array $originalErrors, string $templatePath, ?string
110111
return $errors;
111112
}
112113

113-
public function buildError(Error $originalError, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): ?RuleError
114+
public function buildError(Error $originalError, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): ?IdentifierRuleError
114115
{
115116
$lineMap = $compiledTemplatePath ? $this->lineMapper->getLineMap($compiledTemplatePath) : new LineMap();
116117

@@ -119,6 +120,7 @@ public function buildError(Error $originalError, string $templatePath, ?string $
119120

120121
$ruleErrorBuilder = RuleErrorBuilder::message($error->getMessage())
121122
->file($templatePath)
123+
->identifier('latte.error')
122124
->metadata(array_merge($originalError->getMetadata(), [
123125
'context' => $context === '' ? null : $context,
124126
'is_warning' => $this->isWarning($error->getMessage()),
@@ -138,8 +140,8 @@ public function buildError(Error $originalError, string $templatePath, ?string $
138140
}
139141

140142
/**
141-
* @param RuleError[] $ruleErrors
142-
* @return RuleError[]
143+
* @param IdentifierRuleError[] $ruleErrors
144+
* @return list<IdentifierRuleError>
143145
*/
144146
public function buildRuleErrors(array $ruleErrors): array
145147
{
@@ -182,7 +184,7 @@ public function buildRuleErrors(array $ruleErrors): array
182184
return $newRuleErrors;
183185
}
184186

185-
private function errorSignature(RuleError $error): string
187+
private function errorSignature(IdentifierRuleError $error): string
186188
{
187189
$values = (array)$error;
188190
unset($values['metadata']);

src/Error/Transformer/BlockParameterErrorTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ final class BlockParameterErrorTransformer implements ErrorTransformerInterface
1313
public function transform(Error $error): Error
1414
{
1515
preg_match(self::BLOCK_METHOD, $error->getMessage(), $match);
16-
if (isset($match['block'])) {
16+
if (isset($match[0]) && isset($match['block'])) {
1717
$block = lcfirst(str_replace('_', '-', $match['block']));
1818
$message = $error->getMessage();
1919
// replace method name to block name

src/LatteTemplateResolver/AbstractClassMethodTemplateResolver.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ protected function getClassResult(ReflectionClass $reflectionClass, LatteContext
3535
!$latteContext->methodFinder()->hasAnyAlwaysTerminated($reflectionClass->getName(), $reflectionMethod->getName())
3636
) {
3737
$result->addErrorFromBuilder(RuleErrorBuilder::message("Cannot resolve latte template for {$reflectionClass->getShortName()}::{$reflectionMethod->getName()}().")
38+
->identifier('latte.cannotResolve')
3839
->file($reflectionClass->getFileName() ?? 'unknown')
3940
->line($reflectionMethod->getStartLine()));
4041
}

src/LatteTemplateResolver/LatteTemplateResolverResult.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@
77
use Efabrica\PHPStanLatte\LatteContext\CollectedData\CollectedTemplateRender;
88
use Efabrica\PHPStanLatte\Template\Template;
99
use Efabrica\PHPStanLatte\Template\TemplateContext;
10-
use PHPStan\Rules\RuleError;
10+
use PHPStan\Rules\IdentifierRuleError;
1111
use PHPStan\Rules\RuleErrorBuilder;
1212

1313
final class LatteTemplateResolverResult
1414
{
1515
/** @var array<string, Template> */
1616
private array $templates = [];
1717

18-
/** @var RuleError[] */
18+
/** @var IdentifierRuleError[] */
1919
private array $errors = [];
2020

2121
/**
2222
* @param Template[] $templates
23-
* @param RuleError[] $errors
23+
* @param IdentifierRuleError[] $errors
2424
*/
2525
public function __construct(array $templates = [], array $errors = [])
2626
{
@@ -39,7 +39,7 @@ public function getTemplates(): array
3939
}
4040

4141
/**
42-
* @return RuleError[]
42+
* @return IdentifierRuleError[]
4343
*/
4444
public function getErrors(): array
4545
{
@@ -51,11 +51,14 @@ public function addTemplate(Template $template): void
5151
$this->templates[$template->getSignatureHash()] = $template;
5252
}
5353

54-
public function addError(RuleError $error): void
54+
public function addError(IdentifierRuleError $error): void
5555
{
5656
$this->errors[] = $error;
5757
}
5858

59+
/**
60+
* @param RuleErrorBuilder<IdentifierRuleError> $error
61+
*/
5962
public function addErrorFromBuilder(RuleErrorBuilder $error): void
6063
{
6164
$this->errors[] = $error->build();
@@ -69,11 +72,13 @@ public function addTemplateFromRender(CollectedTemplateRender $templateRender, T
6972
$templatePath = $templateRender->getTemplatePath();
7073
if ($templatePath === null) {
7174
$this->addErrorFromBuilder(RuleErrorBuilder::message('Cannot resolve rendered latte template.')
75+
->identifier('latte.cannotResolve')
7276
->file($templateRender->getFile())
7377
->line($templateRender->getLine()));
7478
return;
7579
} elseif (!is_file($templatePath)) {
7680
$this->addErrorFromBuilder(RuleErrorBuilder::message('Rendered latte template ' . $templatePath . ' does not exist.')
81+
->identifier('latte.notFound')
7782
->file($templateRender->getFile())
7883
->line($templateRender->getLine()));
7984
return;

src/LatteTemplateResolver/Nette/NetteApplicationUIPresenter.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ protected function getClassResult(ReflectionClass $reflectionClass, LatteContext
127127
foreach ($actionDefinition['templatePaths'] as $template) {
128128
if ($template === null) {
129129
$result->addErrorFromBuilder(RuleErrorBuilder::message('Cannot automatically resolve latte template from expression.')
130-
->file($reflectionClass->getFileName() ?? 'unknown')
131-
->line($actionDefinition['line']));
130+
->identifier('latte.cannotResolve')
131+
->file($reflectionClass->getFileName() ?? 'unknown')
132+
->line($actionDefinition['line']));
132133
continue;
133134
}
134135
$result->addTemplate(new Template($template, $reflectionClass->getName(), $actionName, $actionDefinition['templateContext']));
@@ -143,6 +144,7 @@ protected function getClassResult(ReflectionClass $reflectionClass, LatteContext
143144
if ($actionDefinition['defaultTemplate'] === null) {
144145
if (!$actionDefinition['terminated'] && $actionDefinition['templatePaths'] === []) { // might not be rendered at all (for example redirect or use set template path)
145146
$result->addErrorFromBuilder(RuleErrorBuilder::message("Cannot resolve latte template for action $actionName")
147+
->identifier('latte.cannotResolve')
146148
->file($reflectionClass->getFileName() ?? 'unknown')
147149
->line($actionDefinition['line'])
148150
->identifier($actionName));

src/LinkProcessor/PresenterActionLinkProcessor.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,12 @@ public function createLinkExpressions(string $targetName, array $linkParams, arr
6969
if (!$presenterFactory instanceof PresenterFactory) {
7070
return [];
7171
}
72-
$presenterClassName = $presenterFactory->formatPresenterClass($presenterWithModule);
73-
if ($presenterClassName === '') {
72+
if ($presenterWithModule) {
73+
$presenterClassName = $presenterFactory->formatPresenterClass($presenterWithModule);
74+
} else {
75+
$presenterClassName = $this->actualClass;
76+
}
77+
if ($presenterClassName === '' || $presenterClassName === null) {
7478
return [];
7579
}
7680
if (!$this->reflectionProvider->hasClass($presenterClassName)) {

0 commit comments

Comments
 (0)