fix(translator): reject static/instance property redeclaration mismatch (#57) --skip-tests

checkPropertyOverride() compared type, visibility, set-visibility,
readonly and final between a child property and the parent's, but never
Modifiers::STATIC. Redeclaring `public static int $x` as
`public int $x` (or the reverse) was accepted, while Zend fatals with
"Cannot redeclare static A::$x as non static B::$x" (and "Cannot
redeclare non static ... as static ..." in the other direction):
static and instance properties are different kinds of storage and can
never override one another.
master
Alessio Giacobbe 10 hours ago committed by GitHub
parent c6e6997db8
commit 0f1efb52a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      phpunit/code/property_nonstatic_mismatch.php
  2. 14
      phpunit/code/property_static_match.php
  3. 12
      phpunit/code/property_static_mismatch.php
  4. 32
      phpunit/src/StaticPropertyOverrideTest.php
  5. 8
      src/Translator.php

@ -0,0 +1,12 @@
<?php
class A
{
public int $x = 1;
}
class B extends A
{
public static int $x = 2;
}
function main() {}

@ -0,0 +1,14 @@
<?php
class A
{
public static int $x = 1;
public int $y = 1;
}
class B extends A
{
public static int $x = 2;
public int $y = 2;
}
function main() {}

@ -0,0 +1,12 @@
<?php
class A
{
public static int $x = 1;
}
class B extends A
{
public int $x = 2;
}
function main() {}

@ -0,0 +1,32 @@
<?php
use TypePhp\Exception\TestError;
/**
* A static property and an instance property are different kinds of storage;
* Zend forbids redeclaring one as the other in either direction ("Cannot
* redeclare static A::$x as non static B::$x" and vice versa).
*/
class StaticPropertyOverrideTest extends BaseTest
{
public function testMatchingStaticnessCompiles(): void
{
$this->compile('property_static_match.php');
}
public function testStaticCannotBecomeInstance(): void
{
$this->exec(
'Cannot redeclare static `A::$x` as non static `B::$x`',
'property_static_mismatch.php',
);
}
public function testInstanceCannotBecomeStatic(): void
{
$this->exec(
'Cannot redeclare non static `A::$x` as static `B::$x`',
'property_nonstatic_mismatch.php',
);
}
}

@ -5407,6 +5407,14 @@ CODE;
"`{$parentClass}::\${$name}`; property shadowing across inheritance is not allowed");
}
$matchedOverrides[$name] = true;
// A static property and an instance property are different
// kinds of storage; Zend forbids redeclaring one as the
// other in either direction.
if (($childProp->flags & Modifiers::STATIC) !== ($parentProp->flags & Modifiers::STATIC)) {
$this->fatalError($classStmt, ($parentProp->flags & Modifiers::STATIC)
? "Cannot redeclare static `{$parentClass}::\${$name}` as non static `{$className}::\${$name}`"
: "Cannot redeclare non static `{$parentClass}::\${$name}` as static `{$className}::\${$name}`");
}
// PHP inherits get and set independently. A child may
// override only one hook, or redeclare the property
// without hooks while retaining both parent hooks.

Loading…
Cancel
Save