diff --git a/CHANGELOG.md b/CHANGELOG.md index 4256316..67a06c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fixed command execution to properly return error codes when failures occur * Improved error handling in all command implementations * fix empty scope error. #11 + * fix get variable name in InterpolatedString. ex: ${"Hello, {$name}!"} #12 ## v0.0.4 (2025-03-20) diff --git a/src/Parse/VariableParser.php b/src/Parse/VariableParser.php index 9e962b2..d4eaf12 100644 --- a/src/Parse/VariableParser.php +++ b/src/Parse/VariableParser.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; +use PhpParser\Node\Scalar\InterpolatedString; use PhpParser\NodeFinder; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor\NameResolver; @@ -65,9 +66,23 @@ private function collectParseResultPerFunctionLike(array $functionLikes): array $variables = $this->nodeFinder->findInstanceOf($function, Variable::class); foreach ($variables as $variable) { $assigned = $variable->getAttribute('assigned'); - $func->addVariable(new VarReference($variable->name, $variable->getLine(), $assigned === true)); // @phpstan-ignore-line + $func->addVariable(new VarReference($this->getVariableName($variable), $variable->getLine(), $assigned === true)); // @phpstan-ignore-line } return $func; }, $functionLikes); } + + private function getVariableName(Variable $variable): string + { + if ($variable->name instanceof InterpolatedString) { + $parts = $variable->name->parts; + return sprintf('${"%s"}', implode('', array_map(function($part){ + if ($part instanceof Variable) { + return sprintf('{$%s}', $part->name); + } + return $part->value; + }, $parts))); + } + return $variable->name; + } } \ No newline at end of file diff --git a/test/VariableParserTest.php b/test/VariableParserTest.php index 94fe23c..056e1f3 100644 --- a/test/VariableParserTest.php +++ b/test/VariableParserTest.php @@ -153,4 +153,29 @@ public function testParseAssignOperator(): void $this->assertSame(18, $vars[13]->lineNumber); $this->assertSame(true, $vars[13]->assigned); } + + public function testInterpolatedStringFunction(): void + { + $parser = new VariableParser(); + $content = file_get_contents($this->fixtureDir . '/interpolated_string.php'); + $result = $parser->parse($content); + + $this->assertInstanceOf(ParseResult::class, $result); + $functions = $result->functions; + $this->assertCount(1, $functions); + $this->assertSame('test', $functions[0]->name); + $this->assertSame(null, $functions[0]->namespace); + $this->assertCount(3, $functions[0]->getVariables()); + + $vars = $functions[0]->getVariables(); + $this->assertSame('name', $vars[0]->name); + $this->assertSame(3, $vars[0]->lineNumber, 'first $name'); + $this->assertSame(false, $vars[0]->assigned, 'first $name'); + $this->assertSame('${"Hello, {$name}!"}', $vars[1]->name, '${"Hello, {$name}!'); + $this->assertSame(5, $vars[1]->lineNumber, 'interpolated_string'); + $this->assertSame(false, $vars[1]->assigned, 'interpolated_string not reference'); + $this->assertSame('name', $vars[2]->name); + $this->assertSame(5, $vars[2]->lineNumber, 'second $name (10)'); + $this->assertSame(false, $vars[2]->assigned, 'second $name (10) not reference'); + } } \ No newline at end of file diff --git a/test/fixtures/interpolated_string.php b/test/fixtures/interpolated_string.php new file mode 100644 index 0000000..73caf1d --- /dev/null +++ b/test/fixtures/interpolated_string.php @@ -0,0 +1,6 @@ +