From 121a80161634103e278ca1507f8c736742491c56 Mon Sep 17 00:00:00 2001 From: adrew Date: Mon, 31 Jan 2022 21:23:29 +0300 Subject: [PATCH 1/2] Fix object constant inference --- .../Expression/SimpleTypeInferer.php | 15 ++++++- .../Internal/PhpVisitor/ReflectorVisitor.php | 6 ++- tests/ConstantTest.php | 41 +++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php index 5a1bb9975ed..a22a858465f 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php @@ -55,7 +55,8 @@ public static function infer( Aliases $aliases, FileSource $file_source = null, ?array $existing_class_constants = null, - ?string $fq_classlike_name = null + ?string $fq_classlike_name = null, + bool $const_inference = false ): ?Union { if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) { if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) { @@ -431,6 +432,18 @@ public static function infer( } } + if ($const_inference && $stmt instanceof PhpParser\Node\Expr\New_) { + $resolved_class_name = $stmt->class->getAttribute('resolvedName'); + + if (!is_string($resolved_class_name)) { + return null; + } + + return new Union([ + new Type\Atomic\TNamedObject($resolved_class_name) + ]); + } + return null; } diff --git a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php index e99259cfca0..95a6e983a55 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -287,7 +287,11 @@ public function enterNode(PhpParser\Node $node): ?int $this->codebase, new NodeDataProvider(), $const->value, - $this->aliases + $this->aliases, + null, + null, + null, + true ) ?? Type::getMixed(); $fq_const_name = Type::getFQCLNFromString($const->name->name, $this->aliases); diff --git a/tests/ConstantTest.php b/tests/ConstantTest.php index 22250503f13..d1a1af3ea43 100644 --- a/tests/ConstantTest.php +++ b/tests/ConstantTest.php @@ -2,14 +2,55 @@ namespace Psalm\Tests; +use Psalm\Context; use Psalm\Tests\Traits\InvalidCodeAnalysisTestTrait; use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait; +use function getcwd; + +use const DIRECTORY_SEPARATOR; + class ConstantTest extends TestCase { use InvalidCodeAnalysisTestTrait; use ValidCodeAnalysisTestTrait; + public function testUseObjectConstant(): void + { + $file1 = getcwd() . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'file1.php'; + $file2 = getcwd() . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'file2.php'; + + $this->addFile( + $file1, + 'addFile( + $file2, + 'analyzeFile($file1, new Context()); + $this->analyzeFile($file2, new Context()); + } + /** * @return iterable,error_levels?:string[], php_version?: string}> */ From e284b91b82d00200878508cfbfd92dbc506e5cda Mon Sep 17 00:00:00 2001 From: adrew Date: Mon, 31 Jan 2022 22:41:44 +0300 Subject: [PATCH 2/2] Remove redundant flag from SimpleTypeInferer --- .../Analyzer/Statements/Expression/SimpleTypeInferer.php | 5 ++--- src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php | 6 +----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php index a22a858465f..6462c6d1cd4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php @@ -55,8 +55,7 @@ public static function infer( Aliases $aliases, FileSource $file_source = null, ?array $existing_class_constants = null, - ?string $fq_classlike_name = null, - bool $const_inference = false + ?string $fq_classlike_name = null ): ?Union { if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) { if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) { @@ -432,7 +431,7 @@ public static function infer( } } - if ($const_inference && $stmt instanceof PhpParser\Node\Expr\New_) { + if ($stmt instanceof PhpParser\Node\Expr\New_) { $resolved_class_name = $stmt->class->getAttribute('resolvedName'); if (!is_string($resolved_class_name)) { diff --git a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php index 95a6e983a55..e99259cfca0 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -287,11 +287,7 @@ public function enterNode(PhpParser\Node $node): ?int $this->codebase, new NodeDataProvider(), $const->value, - $this->aliases, - null, - null, - null, - true + $this->aliases ) ?? Type::getMixed(); $fq_const_name = Type::getFQCLNFromString($const->name->name, $this->aliases);