Skip to content

Commit 856ca73

Browse files
samsonasikcalebdw
andauthored
[Php81] Handle on ternary on NullToStrictStringFuncCallArgRector (#7091)
* ci: Create skip_existing_casts.php.inc * Closes #7089 * Closes #7089 --------- Co-authored-by: Caleb White <cdwhite3@pm.me>
1 parent 826973c commit 856ca73

2 files changed

Lines changed: 92 additions & 24 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector\Fixture;
4+
5+
final class WithExistingCastOnTernary
6+
{
7+
public function run()
8+
{
9+
return $relpath
10+
. '/' . rawurlencode((string) $this->Get('account_code') ?: $this->Get('customer_id'));
11+
}
12+
13+
public function run2()
14+
{
15+
return $relpath
16+
. '/' . rawurlencode((string) $this->Get('account_code') ?: null);
17+
}
18+
19+
public function Get($fieldname)
20+
{
21+
return $this->{$fieldname} ?? null;
22+
}
23+
}
24+
25+
?>
26+
-----
27+
<?php
28+
29+
namespace Rector\Tests\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector\Fixture;
30+
31+
final class WithExistingCastOnTernary
32+
{
33+
public function run()
34+
{
35+
return $relpath
36+
. '/' . rawurlencode((string) $this->Get('account_code') ?: (string) $this->Get('customer_id'));
37+
}
38+
39+
public function run2()
40+
{
41+
return $relpath
42+
. '/' . rawurlencode((string) $this->Get('account_code') ?: '');
43+
}
44+
45+
public function Get($fieldname)
46+
{
47+
return $this->{$fieldname} ?? null;
48+
}
49+
}
50+
51+
?>

rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
use PhpParser\Node\Arg;
99
use PhpParser\Node\Expr;
1010
use PhpParser\Node\Expr\Cast\String_ as CastString_;
11-
use PhpParser\Node\Expr\ConstFetch;
1211
use PhpParser\Node\Expr\FuncCall;
1312
use PhpParser\Node\Expr\MethodCall;
13+
use PhpParser\Node\Expr\Ternary;
1414
use PhpParser\Node\Identifier;
1515
use PhpParser\Node\Scalar\InterpolatedString;
1616
use PhpParser\Node\Scalar\String_;
@@ -192,51 +192,68 @@ private function processNullToStrictStringOnNodePosition(
192192

193193
$argValue = $args[$position]->value;
194194

195-
if ($argValue instanceof ConstFetch && $this->valueResolver->isNull($argValue)) {
195+
if ($this->valueResolver->isNull($argValue)) {
196196
$args[$position]->value = new String_('');
197197
$funcCall->args = $args;
198198

199199
return $funcCall;
200200
}
201201

202-
$type = $this->nodeTypeResolver->getType($argValue);
203-
if ($type->isString()->yes()) {
202+
if ($this->shouldSkipValue($argValue, $scope, $isTrait)) {
204203
return null;
205204
}
206205

207-
$nativeType = $this->nodeTypeResolver->getNativeType($argValue);
208-
if ($nativeType->isString()->yes()) {
209-
return null;
206+
$parameter = $parametersAcceptor->getParameters()[$position] ?? null;
207+
if ($parameter instanceof ExtendedNativeParameterReflection && $parameter->getType() instanceof UnionType) {
208+
$parameterType = $parameter->getType();
209+
if (! $this->isValidUnionType($parameterType)) {
210+
return null;
211+
}
210212
}
211213

212-
if ($this->shouldSkipType($type)) {
213-
return null;
214+
if ($argValue instanceof Ternary && ! $this->shouldSkipValue($argValue->else, $scope, $isTrait)) {
215+
if ($this->valueResolver->isNull($argValue->else)) {
216+
$argValue->else = new String_('');
217+
} else {
218+
$argValue->else = new CastString_($argValue->else);
219+
}
220+
221+
$args[$position]->value = $argValue;
222+
$funcCall->args = $args;
223+
return $funcCall;
214224
}
215225

216-
if ($argValue instanceof InterpolatedString) {
217-
return null;
226+
$args[$position]->value = new CastString_($argValue);
227+
$funcCall->args = $args;
228+
229+
return $funcCall;
230+
}
231+
232+
private function shouldSkipValue(Expr $expr, Scope $scope, bool $isTrait): bool
233+
{
234+
$type = $this->nodeTypeResolver->getType($expr);
235+
if ($type->isString()->yes()) {
236+
return true;
218237
}
219238

220-
if ($this->isAnErrorType($argValue, $nativeType, $scope)) {
221-
return null;
239+
$nativeType = $this->nodeTypeResolver->getNativeType($expr);
240+
if ($nativeType->isString()->yes()) {
241+
return true;
222242
}
223243

224-
if ($this->shouldSkipTrait($argValue, $type, $isTrait)) {
225-
return null;
244+
if ($this->shouldSkipType($type)) {
245+
return true;
226246
}
227247

228-
$parameter = $parametersAcceptor->getParameters()[$position] ?? null;
229-
if ($parameter instanceof ExtendedNativeParameterReflection && $parameter->getType() instanceof UnionType) {
230-
$parameterType = $parameter->getType();
231-
if (! $this->isValidUnionType($parameterType)) {
232-
return null;
233-
}
248+
if ($expr instanceof InterpolatedString) {
249+
return true;
234250
}
235251

236-
$args[$position]->value = new CastString_($argValue);
237-
$funcCall->args = $args;
252+
if ($this->isAnErrorType($expr, $nativeType, $scope)) {
253+
return true;
254+
}
238255

239-
return $funcCall;
256+
return $this->shouldSkipTrait($expr, $type, $isTrait);
240257
}
241258

242259
private function isValidUnionType(Type $type): bool

0 commit comments

Comments
 (0)