Skip to content

Commit

Permalink
Fixes #9373
Browse files Browse the repository at this point in the history
  • Loading branch information
ygottschalk committed Feb 24, 2023
1 parent 98d3514 commit ad5bf62
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -504,33 +504,6 @@ public static function infer(
]);
}

if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch
&& $stmt->var instanceof PhpParser\Node\Expr\ClassConstFetch
&& $stmt->var->name instanceof PhpParser\Node\Identifier
&& $stmt->name instanceof PhpParser\Node\Identifier
&& in_array($stmt->name->name, ['name', 'value', true])
) {
$enum_fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject(
$stmt->var->class,
$aliases,
);
if ($codebase->classlikes->enumExists($enum_fq_class_name)) {
$enum_storage = $codebase->classlike_storage_provider->get($enum_fq_class_name);
if (isset($enum_storage->enum_cases[$stmt->var->name->name])) {
if ($stmt->name->name === 'value') {
$value = $enum_storage->enum_cases[$stmt->var->name->name]->value;
if (is_string($value)) {
return Type::getString($value);
} elseif (is_int($value)) {
return Type::getInt(false, $value);
}
} elseif ($stmt->name->name === 'name') {
return Type::getString($stmt->var->name->name);
}
}
}
}

return null;
}

Expand Down
21 changes: 21 additions & 0 deletions src/Psalm/Internal/Codebase/ConstantTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayValue;
use Psalm\Internal\Scanner\UnresolvedConstant\ClassConstant;
use Psalm\Internal\Scanner\UnresolvedConstant\Constant;
use Psalm\Internal\Scanner\UnresolvedConstant\EnumNameFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\EnumPropertyFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\EnumValueFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\ScalarValue;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedAdditionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp;
Expand Down Expand Up @@ -331,6 +334,24 @@ public static function resolve(
}
}

if ($c instanceof EnumPropertyFetch) {
if ($classlikes->enumExists($c->fqcln)) {
$enum_storage = $classlikes->getStorageFor($c->fqcln);;
if (isset($enum_storage->enum_cases[$c->case])) {
if ($c instanceof EnumValueFetch) {
$value = $enum_storage->enum_cases[$c->case]->value;
if (is_string($value)) {
return new TLiteralString($value);
} elseif (is_int($value)) {
return new TLiteralInt($value);
}
} elseif ($c instanceof EnumNameFetch) {
return new TLiteralString($c->case);
}
}
}
}

return new TMixed;
}

Expand Down
19 changes: 19 additions & 0 deletions src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayValue;
use Psalm\Internal\Scanner\UnresolvedConstant\ClassConstant;
use Psalm\Internal\Scanner\UnresolvedConstant\Constant;
use Psalm\Internal\Scanner\UnresolvedConstant\EnumNameFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\EnumValueFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\KeyValuePair;
use Psalm\Internal\Scanner\UnresolvedConstant\ScalarValue;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedAdditionOp;
Expand Down Expand Up @@ -297,6 +299,23 @@ public static function getUnresolvedClassConstExpr(
return new ArrayValue($items);
}

if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch
&& $stmt->var instanceof PhpParser\Node\Expr\ClassConstFetch
&& $stmt->var->name instanceof PhpParser\Node\Identifier
&& $stmt->name instanceof PhpParser\Node\Identifier
&& in_array($stmt->name->name, ['name', 'value', true])
) {
$enum_fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject(
$stmt->var->class,
$aliases,
);
if ($stmt->name->name === 'value') {
return new EnumValueFetch($enum_fq_class_name, $stmt->var->name);
} elseif ($stmt->name->name === 'name') {
return new EnumNameFetch($enum_fq_class_name, $stmt->var->name);
}
}

return null;
}

Expand Down
15 changes: 15 additions & 0 deletions src/Psalm/Internal/Scanner/UnresolvedConstant/EnumNameFetch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
* @psalm-immutable
* @internal
*/
class EnumNameFetch extends EnumPropertyFetch
{
public function __construct(string $fqcln, string $case)
{
parent::__construct($fqcln, $case, 'name');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;

/**
* @psalm-immutable
* @internal
*/
abstract class EnumPropertyFetch extends UnresolvedConstantComponent
{
public string $fqcln;

public string $case;

/** @var 'name'|'value' */
public string $name;

/**
* @param string $fqcln
* @param string $case
* @param 'name'|'value' $name
*/
public function __construct(string $fqcln, string $case, string $name)
{
$this->fqcln = $fqcln;
$this->case = $case;
$this->name = $name;
}


}
15 changes: 15 additions & 0 deletions src/Psalm/Internal/Scanner/UnresolvedConstant/EnumValueFetch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
* @psalm-immutable
* @internal
*/
class EnumValueFetch extends EnumPropertyFetch
{
public function __construct(string $fqcln, string $case)
{
parent::__construct($fqcln, $case, 'value');
}
}
Loading

0 comments on commit ad5bf62

Please sign in to comment.