Skip to content

Commit 3bcaa44

Browse files
Compatibility fixes for new versions of PHPStan and Nette (#460)
1 parent 280e5cb commit 3bcaa44

16 files changed

+81
-53
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Change Log
22

33
## [Unreleased][unreleased]
4+
### Fixed
5+
- Compatibility with new Latte versions
46

57
## [0.17.1] - 2024-07-18
68
### Updated

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"require": {
88
"php": ">=7.4 <8.4",
99
"ext-json": "*",
10-
"phpstan/phpstan": "^1.10.50",
10+
"phpstan/phpstan": "^1.12.13",
1111
"phpstan/phpstan-nette": "^1.2.6",
1212
"latte/latte": "^2.11.6 | ^3.0.4",
1313
"nette/utils": "^3.2|^4.0",

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 .*, 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/Compiler/NodeVisitor/LinkNodeVisitor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use PhpParser\Node\Expr\PropertyFetch;
2121
use PhpParser\Node\Expr\StaticCall;
2222
use PhpParser\Node\Name;
23-
use PhpParser\Node\Scalar\LNumber;
23+
use PhpParser\Node\Scalar\String_;
2424
use PhpParser\Node\Stmt\Echo_;
2525
use PhpParser\Node\Stmt\If_;
2626
use PhpParser\NodeVisitorAbstract;
@@ -143,7 +143,7 @@ private function prepareNodes(MethodCall $methodCall, array $attributes): ?array
143143
}
144144

145145
return [
146-
new If_(new Identical(new FuncCall(new Name('mt_rand')), new LNumber(0)), [
146+
new If_(new Identical(new FuncCall(new Name('uniqid')), new String_('random')), [
147147
'stmts' => $expressions,
148148
], $attributes),
149149
];

src/Error/ErrorBuilder.php

Lines changed: 9 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,9 @@ 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./',
56+
'/Property Latte\\\\Runtime\\\\Template::\$parentName .* does not accept mixed./',
5557
];
5658

5759
/** @var string[] */
@@ -89,7 +91,7 @@ public function __construct(
8991

9092
/**
9193
* @param Error[] $originalErrors
92-
* @return RuleError[]
94+
* @return IdentifierRuleError[]
9395
*/
9496
public function buildErrors(array $originalErrors, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): array
9597
{
@@ -110,7 +112,7 @@ public function buildErrors(array $originalErrors, string $templatePath, ?string
110112
return $errors;
111113
}
112114

113-
public function buildError(Error $originalError, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): ?RuleError
115+
public function buildError(Error $originalError, string $templatePath, ?string $compiledTemplatePath, ?string $context = null): ?IdentifierRuleError
114116
{
115117
$lineMap = $compiledTemplatePath ? $this->lineMapper->getLineMap($compiledTemplatePath) : new LineMap();
116118

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

120122
$ruleErrorBuilder = RuleErrorBuilder::message($error->getMessage())
121123
->file($templatePath)
124+
->identifier('latte.error')
122125
->metadata(array_merge($originalError->getMetadata(), [
123126
'context' => $context === '' ? null : $context,
124127
'is_warning' => $this->isWarning($error->getMessage()),
@@ -138,8 +141,8 @@ public function buildError(Error $originalError, string $templatePath, ?string $
138141
}
139142

140143
/**
141-
* @param RuleError[] $ruleErrors
142-
* @return RuleError[]
144+
* @param IdentifierRuleError[] $ruleErrors
145+
* @return list<IdentifierRuleError>
143146
*/
144147
public function buildRuleErrors(array $ruleErrors): array
145148
{
@@ -182,7 +185,7 @@ public function buildRuleErrors(array $ruleErrors): array
182185
return $newRuleErrors;
183186
}
184187

185-
private function errorSignature(RuleError $error): string
188+
private function errorSignature(IdentifierRuleError $error): string
186189
{
187190
$values = (array)$error;
188191
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
}

0 commit comments

Comments
 (0)