fix(resolver): stop corrupting single-segment `use const` imports

parseUse rebuilt the imported constant name by splitting on the last
backslash, but strrpos() returns false for a single-segment name:
`use const PHP_EOL;` registered the import as `\HP_EOL`
(substr($id, false + 1) drops the first character), and the compiled
program failed at runtime with `Undefined constant "HP_EOL"`.

$id is already the fully qualified constant name, so store it directly.
For multi-segment imports the removed recomposition produced the same
value, so their behavior is unchanged.
master
Alessio Giacobbe 7 days ago
parent b493ac79c5
commit 96ab6a53ef
No known key found for this signature in database
  1. 10
      src/Resolver/DeclarationSymbolTrait.php
  2. 28
      tests/compiler/namespace/use-const-single-segment.phpt

@ -80,11 +80,11 @@ trait DeclarationSymbolTrait
if ($type === Node\Stmt\Use_::TYPE_FUNCTION) { if ($type === Node\Stmt\Use_::TYPE_FUNCTION) {
$this->useFunctions[$alias] = $id; $this->useFunctions[$alias] = $id;
} elseif ($type === Node\Stmt\Use_::TYPE_CONSTANT) { } elseif ($type === Node\Stmt\Use_::TYPE_CONSTANT) {
$lastIndex = strrpos($id, '\\'); // $id is already the fully qualified constant name. Splitting
$cn = substr($id, $lastIndex + 1); // and re-joining it on `\` corrupted single-segment imports:
$ns = substr($id, 0, $lastIndex); // `use const PHP_EOL;` resolved to `\HP_EOL` because
$fullName = $ns . '\\' . $cn; // strrpos() returns false when there is no separator.
$this->useConstants[$alias] = $fullName; $this->useConstants[$alias] = $id;
} else { } else {
$idLower = strtolower($id); $idLower = strtolower($id);
if ($idLower === 'native_types') { if ($idLower === 'native_types') {

@ -0,0 +1,28 @@
--TEST--
use const with a single-segment (global) constant name
--FILE--
<?php
namespace App {
use const PHP_EOL;
const ANSWER = 42;
function hello(): string
{
return "hello" . PHP_EOL;
}
}
namespace {
use const App\ANSWER;
function main(): void
{
echo \App\hello();
echo ANSWER, "\n";
}
}
?>
--EXPECT--
hello
42
Loading…
Cancel
Save