Skip to content

Commit c31ea7e

Browse files
committed
Implement remaining Magic-Const Handlers
1 parent d7482af commit c31ea7e

File tree

7 files changed

+336
-0
lines changed

7 files changed

+336
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Class_;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Class_>
20+
*/
21+
#[AutowiredService]
22+
final class MagicClassHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Class_;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Function_;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Function_>
20+
*/
21+
#[AutowiredService]
22+
final class MagicFunctionHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Function_;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Method;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Method>
20+
*/
21+
#[AutowiredService]
22+
final class MagicMethodHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Method;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Namespace_;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Namespace_>
20+
*/
21+
#[AutowiredService]
22+
final class MagicNamespaceHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Namespace_;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Property;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Property>
20+
*/
21+
#[AutowiredService]
22+
final class MagicPropertyHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Property;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Scalar\MagicConst\Trait_;
8+
use PhpParser\Node\Stmt;
9+
use PHPStan\Analyser\ExpressionContext;
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+
use PHPStan\Reflection\InitializerExprContext;
16+
use PHPStan\Reflection\InitializerExprTypeResolver;
17+
18+
/**
19+
* @implements ExprHandler<Trait_>
20+
*/
21+
#[AutowiredService]
22+
final class MagicTraitHandler implements ExprHandler
23+
{
24+
25+
public function __construct(private InitializerExprTypeResolver $initializerExprTypeResolver)
26+
{
27+
}
28+
29+
public function supports(Expr $expr): bool
30+
{
31+
return $expr instanceof Trait_;
32+
}
33+
34+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
35+
{
36+
yield from [];
37+
38+
$initializerContext = InitializerExprContext::fromScope($scope);
39+
$type = $this->initializerExprTypeResolver->getType($expr, $initializerContext);
40+
41+
return new ExprAnalysisResult(
42+
$type,
43+
$type,
44+
$scope,
45+
hasYield: false,
46+
isAlwaysTerminating: false,
47+
throwPoints: [],
48+
impurePoints: [],
49+
specifiedTruthyTypes: new SpecifiedTypes(),
50+
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedNullTypes: new SpecifiedTypes(),
52+
);
53+
}
54+
55+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,12 @@ function doFoo(): void {
469469
assertType('literal-string&non-falsy-string', __DIR__);
470470
assertType('literal-string&non-falsy-string', __FILE__);
471471
assertType('471', __LINE__);
472+
assertType("'GeneratorNodeScopeResolverTest'", __NAMESPACE__);
473+
assertType("'GeneratorNodeScopeResolverTest\\\\MagicConstUser'", __CLASS__);
474+
assertType("''", __TRAIT__);
475+
assertType("'doFoo'", __FUNCTION__);
476+
assertType("'GeneratorNodeScopeResolverTest\\\\MagicConstUser::doFoo'", __METHOD__);
477+
assertType("''", __PROPERTY__);
472478
}
473479
}
474480

0 commit comments

Comments
 (0)