fix(closure): handle static variables in closure use references

- Added check for staticVars when processing closure use references
- Prevented redeclaration of static variables as local variables in closures
- Updated variable resolution logic to include static variable scope
- Added comprehensive test case for static variable closure reference behavior
- Fixed variable name collision in preprocessor class constant handling
- Updated version number to 0.4.1
pull/34/head v0.4.1
韩天峰 1 month ago
parent a142cb8949
commit 89799b9b8c
  1. 3
      src/Generator/ClosureGenerator.php
  2. 6
      src/Preprocessor.php
  3. 2
      src/Translator.php
  4. 26
      tests/compiler/static/static-vars-closure-reference.phpt

@ -196,7 +196,8 @@ trait ClosureGenerator
}
if ($useItem->byRef) {
// 闭包的 use 语法,若为引用类型,可以就地创建变量
if (!isset($oriContext->localVars[$var])) {
if (!isset($oriContext->localVars[$var])
&& !isset($oriContext->staticVars[$var])) {
$oriContext->localVars[$var] = Type::REF;
}
$useVars[] = $this->convertToRef($useItem->var);

@ -920,10 +920,10 @@ class Preprocessor extends CompilerBase
if ($value instanceof Node\Expr\ClassConstFetch
&& $this->isNameExpr($value->class)
&& $this->isIdExpr($value->name)) {
$class = $this->getResolvedPhpName($value->class);
$targetClass = $this->getResolvedPhpName($value->class);
$constant = $value->name->toString();
if (strtolower($constant) === 'class') {
return $class;
return $targetClass;
}
$targets = [
'Int' => Type::INT,
@ -939,7 +939,7 @@ class Preprocessor extends CompilerBase
'Stream' => Type::STREAM,
'Box' => Type::BOX,
];
if (strcasecmp($class, 'Type') === 0 && isset($targets[$constant])) {
if (strcasecmp($targetClass, 'Type') === 0 && isset($targets[$constant])) {
return $targets[$constant];
}
}

@ -58,7 +58,7 @@ class Translator extends Preprocessor
use ResourceCompilationTrait;
use ClassConstantValueTrait;
public const string VERSION = '0.4.0';
public const string VERSION = '0.4.1';
public const string APP_NAME = 'TypePHP Compiler (AOT)';
protected const string MODULE_NAME_PREFIX = 'app_';

@ -0,0 +1,26 @@
--TEST--
static variable captured by reference is not redeclared as a local variable
--FILE--
<?php
function getValue(): int
{
static $value = null;
if ($value === null) {
$value = 0;
$increment = static function () use (&$value): void {
$value++;
};
$increment();
}
return $value;
}
function main(): void
{
var_dump(getValue());
var_dump(getValue());
}
?>
--EXPECT--
int(1)
int(1)
Loading…
Cancel
Save