Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add #[\Deprecated] Attribute #11293

Draft
wants to merge 38 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4395ef4
Add #[\Deprecated] attribute
beberlei May 22, 2023
4709c9d
Add Deprecated::$message to stub
TimWolla Apr 15, 2024
5c0f248
Add closing PHP tags to #[\Deprecated] tests
TimWolla Apr 15, 2024
f9dc405
Move zend_deprecated_function call after SAVE_OPLINE()
beberlei Apr 14, 2024
e6c3a6c
Add test showing behavior when deprecations are converted to exeption…
beberlei Apr 15, 2024
24aeeea
Ensure that the Deprecated::$message property is treated as readonly …
TimWolla Apr 15, 2024
9b0155e
Move #[\Deprecated] tests into a dedicated directory
TimWolla Apr 15, 2024
5637768
Clean up #[\Deprecated] tests
TimWolla Apr 15, 2024
782a577
Make #[\Deprecated]’s code E_USER_DEPRECATED
TimWolla Apr 15, 2024
886c298
Handle NUL bytes in #[\Deprecated] message
TimWolla Apr 15, 2024
5641e17
Improve handling of empty #[\Deprecated] message
TimWolla Apr 15, 2024
e1d058a
Simplify implementation of zend_deprecated_function()
TimWolla Apr 15, 2024
73d6329
Expose the #[\Deprecated] CE
TimWolla Apr 15, 2024
8d271bb
Improve type validation for the Deprecated attribute
TimWolla Apr 15, 2024
2be5d73
Add Reflection test for #[\Deprecated]
TimWolla Apr 18, 2024
ce49812
Add support for `#[\Deprecated]` to stubs
TimWolla Apr 19, 2024
6364932
Add Reflection test to ext/zend_test/tests/attribute-deprecated.phpt
TimWolla Apr 23, 2024
19716d1
Fix reference counting in zend_deprecated_function()
TimWolla Apr 23, 2024
fce0cc4
Disable Opcache inlining of deprecated functions
TimWolla Apr 23, 2024
7ec1696
Add closure test for `#[\Deprecated]`
TimWolla Apr 25, 2024
d9ab849
Add `__construct()` and `__destruct()` test for `#[\Deprecated]`
TimWolla Apr 25, 2024
bb7e29a
Test that `#[\Deprecated]` functions are not executed when error hand…
TimWolla Apr 25, 2024
02c4157
Fix stack-of-after-scope
TimWolla Apr 26, 2024
2cd442f
Consistently UNEXPECTED the exception check after `zend_deprecated_fu…
TimWolla Apr 26, 2024
c674a1d
Add test that the `#[\Deprecated]` message may come from a constant
TimWolla Apr 26, 2024
2861973
Only go through `Deprecated::__construct()` for non-strings
TimWolla Apr 30, 2024
a4d0c11
Add additional tests for deprecated error and exception handlers
TimWolla Apr 30, 2024
da62630
Add test for deprecation messages coming from protected class constants
TimWolla Apr 30, 2024
bc55fc7
Fix #[\Deprecated] for JIT
TimWolla Apr 30, 2024
4496eb8
Add support for class constants and enum cases for #[\Deprecated]
TimWolla Apr 30, 2024
b9420f4
Fix `#[\Deprecated]` for the `constant()` function
TimWolla Apr 30, 2024
78de5b1
Merge branch 'master' into DeprecatedAttribute
TimWolla Apr 30, 2024
f9732a2
Test ReflectionClassConstant::isDeprecated() for userland constants
TimWolla May 2, 2024
d0bf4f0
Reorganize tests for #[\Deprecated]
TimWolla May 2, 2024
3670704
Add additional class constant deprecation tests
TimWolla May 2, 2024
f650d8c
Add support for adding the `#[\Deprecated]` attribute to class consta…
TimWolla May 2, 2024
abfe66c
Test deprecated class constants as part of constant expressions
TimWolla May 2, 2024
7f4850b
Test deprecated class constants with values unknown at compile time
TimWolla May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions Zend/tests/attributes/deprecated/001.phpt
@@ -0,0 +1,15 @@
--TEST--
#[\Deprecated]: $message property is readonly.
--FILE--
<?php

$d = new \Deprecated("foo");
$d->__construct("bar");

?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot modify readonly property Deprecated::$message in %s:%d
Stack trace:
#0 %s(%d): Deprecated->__construct('bar')
#1 {main}
thrown in %s on line %d
43 changes: 43 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/001.phpt
@@ -0,0 +1,43 @@
--TEST--
#[\Deprecated]: Class Constants.
--FILE--
<?php

class Clazz {
#[\Deprecated]
public const TEST = 1;

#[\Deprecated()]
public const TEST2 = 2;

#[\Deprecated("use Clazz::TEST instead")]
public const TEST3 = 3;

#[\Deprecated]
public const TEST4 = 4;

#[\Deprecated]
public const TEST5 = 5;
}

var_dump(Clazz::TEST);
var_dump(Clazz::TEST2);
var_dump(Clazz::TEST3);

var_dump(constant('Clazz::TEST4'));
var_dump(defined('Clazz::TEST5'));

?>
--EXPECTF--
Deprecated: Constant Clazz::TEST is deprecated in %s on line %d
int(1)

Deprecated: Constant Clazz::TEST2 is deprecated in %s on line %d
int(2)

Deprecated: Constant Clazz::TEST3 is deprecated, use Clazz::TEST instead in %s on line %d
int(3)

Deprecated: Constant Clazz::TEST4 is deprecated in %s on line %d
int(4)
bool(true)
21 changes: 21 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/002.phpt
@@ -0,0 +1,21 @@
--TEST--
#[\Deprecated]: Enum cases.
--FILE--
<?php

enum E {
#[\Deprecated]
case Test;

#[\Deprecated("use E::Test instead")]
case Test2;
}

E::Test;
E::Test2;

?>
--EXPECTF--
Deprecated: Enum case E::Test is deprecated in %s on line %d

Deprecated: Enum case E::Test2 is deprecated, use E::Test instead in %s on line %d
17 changes: 17 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/003.phpt
@@ -0,0 +1,17 @@
--TEST--
#[\Deprecated]: ReflectionClassConstant::isDeprecated() returns true.
--FILE--
<?php

class Clazz {
#[\Deprecated]
public const TEST = 'test';
}


$r = new ReflectionClassConstant('Clazz', 'TEST');
var_dump($r->isDeprecated());

?>
--EXPECTF--
bool(true)
21 changes: 21 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/004.phpt
@@ -0,0 +1,21 @@
--TEST--
#[\Deprecated]: Code is E_USER_DEPRECATED for class constants.
--FILE--
<?php

set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
var_dump($errno, E_USER_DEPRECATED, $errno === E_USER_DEPRECATED);
});

class Clazz {
#[\Deprecated]
public const TEST = 1;
}

Clazz::TEST;

?>
--EXPECT--
int(16384)
int(16384)
bool(true)
26 changes: 26 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/005.phpt
@@ -0,0 +1,26 @@
--TEST--
#[\Deprecated]: Using the value of a deprecated class constant as the deprecation message.
--FILE--
<?php

class Clazz {
#[\Deprecated(self::TEST)]
public const TEST = "from itself";

#[\Deprecated]
public const TEST2 = "from another";

#[\Deprecated(self::TEST2)]
public const TEST3 = 1;
}

Clazz::TEST;
Clazz::TEST3;

?>
--EXPECTF--
Deprecated: Constant Clazz::TEST is deprecated, from itself in %s on line %d

Deprecated: Constant Clazz::TEST2 is deprecated in %s on line %d

Deprecated: Constant Clazz::TEST3 is deprecated, from another in %s on line %d
36 changes: 36 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/006.phpt
@@ -0,0 +1,36 @@
--TEST--
#[\Deprecated]: Using the value of a deprecated class constant as the deprecation message with a throwing error handler.
--FILE--
<?php

set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
});

class Clazz {
#[\Deprecated(self::TEST)]
public const TEST = "from itself";

#[\Deprecated]
public const TEST2 = "from another";

#[\Deprecated(self::TEST2)]
public const TEST3 = 1;
}

try {
Clazz::TEST;
} catch (ErrorException $e) {
echo "Caught: ", $e->getMessage(), PHP_EOL;
}

try {
Clazz::TEST3;
} catch (ErrorException $e) {
echo "Caught: ", $e->getMessage(), PHP_EOL;
}

?>
--EXPECT--
Caught: Constant Clazz::TEST is deprecated, from itself
Caught: Constant Clazz::TEST2 is deprecated
23 changes: 23 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/007.phpt
@@ -0,0 +1,23 @@
--TEST--
#[\Deprecated]: Using the value of a deprecated class constant in a constant expression.
--FILE--
<?php

class Clazz {
#[\Deprecated("prefix")]
public const PREFIX = "prefix";

#[\Deprecated("suffix")]
public const SUFFIX = "suffix";

public const CONSTANT = self::PREFIX . self::SUFFIX;
}

var_dump(Clazz::CONSTANT);

?>
--EXPECTF--
Deprecated: Constant Clazz::PREFIX is deprecated, prefix in %s on line %d

Deprecated: Constant Clazz::SUFFIX is deprecated, suffix in %s on line %d
string(12) "prefixsuffix"
21 changes: 21 additions & 0 deletions Zend/tests/attributes/deprecated/class_constants/008.phpt
@@ -0,0 +1,21 @@
--TEST--
#[\Deprecated]: Class constant with value unknown at compile time.
--FILE--
<?php

define('SUFFIX', random_int(1, 2) == 1 ? 'a' : 'b');

class Clazz {
#[\Deprecated]
public const CONSTANT = self::class . '-' . SUFFIX;
}

$value = Clazz::CONSTANT;
var_dump($value);
var_dump($value === 'Clazz-' . SUFFIX);

?>
--EXPECTF--
Deprecated: Constant Clazz::CONSTANT is deprecated in %s on line %d
string(7) "Clazz-%c"
bool(true)
79 changes: 79 additions & 0 deletions Zend/tests/attributes/deprecated/functions/001.phpt
@@ -0,0 +1,79 @@
--TEST--
#[\Deprecated]: Functions and Methods.
--FILE--
<?php

error_reporting(E_ALL | E_DEPRECATED);
ini_set('display_errors', true);

#[\Deprecated]
function test() {
}

#[\Deprecated("use test() instead")]
function test2() {
}

class Clazz {
#[\Deprecated]
function test() {
}

#[\Deprecated("use test() instead")]
function test2() {
}
}

$closure = #[\Deprecated] function() {
};

$closure2 = #[\Deprecated] function() {
};

class Constructor {
#[\Deprecated]
public function __construct() {
}

#[\Deprecated]
public function __destruct() {
}
}

test();
test2();
call_user_func("test");

$cls = new Clazz();
$cls->test();
$cls->test2();

call_user_func([$cls, "test"]);

$closure();

$closure2();

new Constructor();

?>
--EXPECTF--
Deprecated: Function test() is deprecated in %s

Deprecated: Function test2() is deprecated, use test() instead in %s

Deprecated: Function test() is deprecated in %s

Deprecated: Method Clazz::test() is deprecated in %s

Deprecated: Method Clazz::test2() is deprecated, use test() instead in %s

Deprecated: Method Clazz::test() is deprecated in %s

Deprecated: Function {closure:%s:%d}() is deprecated in %s on line %d

Deprecated: Function {closure:%s:%d}() is deprecated in %s on line %d

Deprecated: Method Constructor::__construct() is deprecated in %s on line %d

Deprecated: Method Constructor::__destruct() is deprecated in %s on line %d
40 changes: 40 additions & 0 deletions Zend/tests/attributes/deprecated/functions/002.phpt
@@ -0,0 +1,40 @@
--TEST--
#[\Deprecated]: Instantiating via Reflection.
--FILE--
<?php

#[\Deprecated]
function test1() {
}

#[\Deprecated()]
function test2() {
}

#[\Deprecated("use test() instead")]
function test3() {
}

$reflection = new ReflectionFunction('test1');
var_dump($reflection->getAttributes()[0]->newInstance());

$reflection = new ReflectionFunction('test2');
var_dump($reflection->getAttributes()[0]->newInstance());

$reflection = new ReflectionFunction('test3');
var_dump($reflection->getAttributes()[0]->newInstance());

?>
--EXPECTF--
object(Deprecated)#%d (1) {
["message"]=>
NULL
}
object(Deprecated)#%d (1) {
["message"]=>
NULL
}
object(Deprecated)#%d (1) {
["message"]=>
string(18) "use test() instead"
}
14 changes: 14 additions & 0 deletions Zend/tests/attributes/deprecated/functions/003.phpt
@@ -0,0 +1,14 @@
--TEST--
#[\Deprecated]: Type validation of $message parameter with int.
--FILE--
<?php

#[\Deprecated(1234)]
function test() {
}

test();

?>
--EXPECTF--
Deprecated: Function test() is deprecated, 1234 in %s on line %d