Skip to content

Commit d91b0f2

Browse files
staabmondrejmirtes
authored andcommitted
Implement Cast*Handler
1 parent 75f223e commit d91b0f2

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser\Generator\ExprHandler;
4+
5+
use Generator;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Stmt;
8+
use PHPStan\Analyser\ExpressionContext;
9+
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
10+
use PHPStan\Analyser\Generator\ExprAnalysisResult;
11+
use PHPStan\Analyser\Generator\ExprHandler;
12+
use PHPStan\Analyser\Generator\GeneratorScope;
13+
use PHPStan\Analyser\SpecifiedTypes;
14+
use PHPStan\DependencyInjection\AutowiredService;
15+
16+
/**
17+
* @implements ExprHandler<Expr\Cast\Array_>
18+
*/
19+
#[AutowiredService]
20+
final class CastArrayHandler implements ExprHandler
21+
{
22+
23+
public function supports(Expr $expr): bool
24+
{
25+
return $expr instanceof Expr\Cast\Array_;
26+
}
27+
28+
public function analyseExpr(
29+
Stmt $stmt,
30+
Expr $expr,
31+
GeneratorScope $scope,
32+
ExpressionContext $context,
33+
?callable $alternativeNodeCallback,
34+
): Generator
35+
{
36+
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
37+
38+
return new ExprAnalysisResult(
39+
$exprResult->type->toArray(),
40+
$exprResult->nativeType->toArray(),
41+
$scope,
42+
hasYield: false,
43+
isAlwaysTerminating: false,
44+
throwPoints: [],
45+
impurePoints: [],
46+
specifiedTruthyTypes: new SpecifiedTypes(),
47+
specifiedFalseyTypes: new SpecifiedTypes(),
48+
specifiedNullTypes: new SpecifiedTypes(),
49+
);
50+
}
51+
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser\Generator\ExprHandler;
4+
5+
use Generator;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Stmt;
8+
use PHPStan\Analyser\ExpressionContext;
9+
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
10+
use PHPStan\Analyser\Generator\ExprAnalysisResult;
11+
use PHPStan\Analyser\Generator\ExprHandler;
12+
use PHPStan\Analyser\Generator\GeneratorScope;
13+
use PHPStan\Analyser\SpecifiedTypes;
14+
use PHPStan\DependencyInjection\AutowiredService;
15+
16+
/**
17+
* @implements ExprHandler<Expr\Cast\Bool_>
18+
*/
19+
#[AutowiredService]
20+
final class CastBoolHandler implements ExprHandler
21+
{
22+
23+
public function supports(Expr $expr): bool
24+
{
25+
return $expr instanceof Expr\Cast\Bool_;
26+
}
27+
28+
public function analyseExpr(
29+
Stmt $stmt,
30+
Expr $expr,
31+
GeneratorScope $scope,
32+
ExpressionContext $context,
33+
?callable $alternativeNodeCallback,
34+
): Generator
35+
{
36+
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
37+
38+
return new ExprAnalysisResult(
39+
$exprResult->type->toBoolean(),
40+
$exprResult->nativeType->toBoolean(),
41+
$scope,
42+
hasYield: false,
43+
isAlwaysTerminating: false,
44+
throwPoints: [],
45+
impurePoints: [],
46+
specifiedTruthyTypes: new SpecifiedTypes(),
47+
specifiedFalseyTypes: new SpecifiedTypes(),
48+
specifiedNullTypes: new SpecifiedTypes(),
49+
);
50+
}
51+
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser\Generator\ExprHandler;
4+
5+
use Generator;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Stmt;
8+
use PHPStan\Analyser\ExpressionContext;
9+
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
10+
use PHPStan\Analyser\Generator\ExprAnalysisResult;
11+
use PHPStan\Analyser\Generator\ExprHandler;
12+
use PHPStan\Analyser\Generator\GeneratorScope;
13+
use PHPStan\Analyser\SpecifiedTypes;
14+
use PHPStan\DependencyInjection\AutowiredService;
15+
16+
/**
17+
* @implements ExprHandler<Expr\Cast\Double>
18+
*/
19+
#[AutowiredService]
20+
final class CastDoubleHandler implements ExprHandler
21+
{
22+
23+
public function supports(Expr $expr): bool
24+
{
25+
return $expr instanceof Expr\Cast\Double;
26+
}
27+
28+
public function analyseExpr(
29+
Stmt $stmt,
30+
Expr $expr,
31+
GeneratorScope $scope,
32+
ExpressionContext $context,
33+
?callable $alternativeNodeCallback,
34+
): Generator
35+
{
36+
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
37+
38+
return new ExprAnalysisResult(
39+
$exprResult->type->toFloat(),
40+
$exprResult->nativeType->toFloat(),
41+
$scope,
42+
hasYield: false,
43+
isAlwaysTerminating: false,
44+
throwPoints: [],
45+
impurePoints: [],
46+
specifiedTruthyTypes: new SpecifiedTypes(),
47+
specifiedFalseyTypes: new SpecifiedTypes(),
48+
specifiedNullTypes: new SpecifiedTypes(),
49+
);
50+
}
51+
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser\Generator\ExprHandler;
4+
5+
use Generator;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Stmt;
8+
use PHPStan\Analyser\ExpressionContext;
9+
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
10+
use PHPStan\Analyser\Generator\ExprAnalysisResult;
11+
use PHPStan\Analyser\Generator\ExprHandler;
12+
use PHPStan\Analyser\Generator\GeneratorScope;
13+
use PHPStan\Analyser\SpecifiedTypes;
14+
use PHPStan\DependencyInjection\AutowiredService;
15+
16+
/**
17+
* @implements ExprHandler<Expr\Cast\String_>
18+
*/
19+
#[AutowiredService]
20+
final class CastStringHandler implements ExprHandler
21+
{
22+
23+
public function supports(Expr $expr): bool
24+
{
25+
return $expr instanceof Expr\Cast\String_;
26+
}
27+
28+
public function analyseExpr(
29+
Stmt $stmt,
30+
Expr $expr,
31+
GeneratorScope $scope,
32+
ExpressionContext $context,
33+
?callable $alternativeNodeCallback,
34+
): Generator
35+
{
36+
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
37+
38+
return new ExprAnalysisResult(
39+
$exprResult->type->toString(),
40+
$exprResult->nativeType->toString(),
41+
$scope,
42+
hasYield: false,
43+
isAlwaysTerminating: false,
44+
throwPoints: [],
45+
impurePoints: [],
46+
specifiedTruthyTypes: new SpecifiedTypes(),
47+
specifiedFalseyTypes: new SpecifiedTypes(),
48+
specifiedNullTypes: new SpecifiedTypes(),
49+
);
50+
}
51+
52+
}

tests/PHPStan/Analyser/Generator/data/gnsr.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@ public function doSpaceship($a, $b, string $c, string $d): void
236236
assertNativeType('int<-1, 1>', $c <=> $d);
237237
}
238238

239+
function doCast() {
240+
$a = '1';
241+
242+
assertType('1', (int) $a);
243+
assertType("array{'1'}", (array) $a);
244+
// assertType("array{'1'}", (object) $a);
245+
assertType('1.0', (double) $a);
246+
assertType('true', (bool) $a);
247+
assertType("'1'", (string) $a);
248+
}
249+
239250
}
240251

241252
function (): void {

0 commit comments

Comments
 (0)