Skip to content

Commit 0e3e89c

Browse files
committed
Implement constants in traits
1 parent 9bae9ab commit 0e3e89c

22 files changed

+510
-61
lines changed

Zend/tests/traits/constant_001.phpt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
Trying to access a constant on Trait via a Class
3+
--FILE--
4+
<?php
5+
6+
trait Foo {
7+
public const A = 42;
8+
9+
public function f1(): void {
10+
echo self::A, PHP_EOL;
11+
echo static::A, PHP_EOL;
12+
echo $this::A, PHP_EOL;
13+
}
14+
}
15+
16+
class Base {
17+
use Foo;
18+
19+
public function f2(): void {
20+
echo self::A, PHP_EOL;
21+
echo static::A, PHP_EOL;
22+
}
23+
}
24+
25+
class Derived extends Base {
26+
public function f3(): void {
27+
echo self::A, PHP_EOL;
28+
echo static::A, PHP_EOL;
29+
echo parent::A, PHP_EOL;
30+
}
31+
}
32+
33+
echo Base::A, PHP_EOL;
34+
echo (new Base)::A, PHP_EOL;
35+
(new Base)->f1();
36+
(new Base)->f2();
37+
echo Derived::A, PHP_EOL;
38+
echo (new Derived)::A, PHP_EOL;
39+
(new Derived)->f3();
40+
?>
41+
--EXPECTF--
42+
42
43+
42
44+
42
45+
42
46+
42
47+
42
48+
42
49+
42
50+
42
51+
42
52+
42
53+
42

Zend/tests/traits/constant_002.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Defining a constant in both trait and its composing class with the same name, visibility, finality and value is allowed
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait1 {
7+
public const A = 42;
8+
}
9+
10+
trait TestTrait2 {
11+
use TestTrait1;
12+
public const A = 42;
13+
}
14+
15+
trait TestTrait3 {
16+
use TestTrait2;
17+
public const A = 42;
18+
}
19+
20+
class ComposingClass {
21+
use TestTrait1;
22+
use TestTrait3;
23+
public const A = 42;
24+
}
25+
26+
echo ComposingClass::A, PHP_EOL;
27+
?>
28+
--EXPECTF--
29+
42

Zend/tests/traits/constant_003.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Non-final Constants in traits can be overridden in derived classes
3+
--FILE--
4+
<?php
5+
6+
trait Foo {
7+
public const A = 123;
8+
}
9+
10+
class Base {
11+
use Foo;
12+
}
13+
14+
class Derived extends Base {
15+
public const A = 456;
16+
}
17+
18+
echo Derived::A, PHP_EOL;
19+
?>
20+
--EXPECTF--
21+
456

Zend/tests/traits/constant_004.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Trying to access a constant on trait via the name of trait causes a Fatal error
3+
--FILE--
4+
<?php
5+
6+
trait Foo {
7+
const A = 1;
8+
}
9+
10+
class Bar {
11+
use Foo;
12+
}
13+
14+
echo Foo::A, PHP_EOL;
15+
?>
16+
--EXPECTF--
17+
Fatal error: Uncaught Error: Cannot access trait constant Foo::A directly in %s:%d
18+
Stack trace:
19+
#0 {main}
20+
thrown in %s on line %d

Zend/tests/traits/constant_005.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Conflicting constants in composing classes with different visibility modifiers should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait {
7+
public const Constant = 42;
8+
}
9+
10+
echo "PRE-CLASS-GUARD\n";
11+
12+
class ComposingClass {
13+
use TestTrait;
14+
private const Constant = 42;
15+
}
16+
17+
echo "POST-CLASS-GUARD\n";
18+
?>
19+
--EXPECTF--
20+
PRE-CLASS-GUARD
21+
22+
Fatal error: ComposingClass and TestTrait define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_006.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Conflicting constants in composing classes with different values should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait {
7+
public const Constant = 123;
8+
}
9+
10+
echo "PRE-CLASS-GUARD\n";
11+
12+
class ComposingClass {
13+
use TestTrait;
14+
public const Constant = 456;
15+
}
16+
17+
echo "POST-CLASS-GUARD\n";
18+
?>
19+
--EXPECTF--
20+
PRE-CLASS-GUARD
21+
22+
Fatal error: ComposingClass and TestTrait define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_007.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Conflicting constants in composing classes with different finality should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait {
7+
public const Constant = 42;
8+
}
9+
10+
echo "PRE-CLASS-GUARD\n";
11+
12+
class ComposingClass {
13+
use TestTrait;
14+
public final const Constant = 42;
15+
}
16+
17+
echo "POST-CLASS-GUARD\n";
18+
?>
19+
--EXPECTF--
20+
PRE-CLASS-GUARD
21+
22+
Fatal error: ComposingClass and TestTrait define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_008.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Conflicting constants in another traits in same composing classes with different visibility modifiers should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait Trait1 {
7+
public const Constant = 42;
8+
}
9+
10+
trait Trait2 {
11+
private const Constant = 42;
12+
}
13+
14+
echo "PRE-CLASS-GUARD\n";
15+
16+
class TraitsTest {
17+
use Trait1;
18+
use Trait2;
19+
}
20+
21+
echo "POST-CLASS-GUARD\n";
22+
?>
23+
--EXPECTF--
24+
PRE-CLASS-GUARD
25+
26+
Fatal error: Trait1 and Trait2 define the same constant (Constant) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_009.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Conflicting constants in another traits in same composing classes with different values should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait Trait1 {
7+
public const Constant = 123;
8+
}
9+
10+
trait Trait2 {
11+
public const Constant = 456;
12+
}
13+
14+
echo "PRE-CLASS-GUARD\n";
15+
16+
class TraitsTest {
17+
use Trait1;
18+
use Trait2;
19+
}
20+
21+
echo "POST-CLASS-GUARD\n";
22+
?>
23+
--EXPECTF--
24+
PRE-CLASS-GUARD
25+
26+
Fatal error: Trait1 and Trait2 define the same constant (Constant) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_010.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Conflicting constants in another traits in same composing classes with different finality should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait {
7+
public const Constant = 42;
8+
}
9+
10+
echo "PRE-CLASS-GUARD\n";
11+
12+
class ComposingClass {
13+
use TestTrait;
14+
public final const Constant = 42;
15+
}
16+
17+
echo "POST-CLASS-GUARD\n";
18+
?>
19+
--EXPECTF--
20+
PRE-CLASS-GUARD
21+
22+
Fatal error: ComposingClass and TestTrait define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_011.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Conflicting constants in a trait and another trait using it with different visibility modifiers should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait Trait1 {
7+
public const Constant = 42;
8+
}
9+
10+
trait Trait2 {
11+
use Trait1;
12+
private const Constant = 42;
13+
}
14+
?>
15+
--EXPECTF--
16+
Fatal error: Trait2 and Trait1 define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_012.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Conflicting constants in a trait and another trait using it with different values should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait Trait1 {
7+
public const Constant = 123;
8+
}
9+
10+
trait Trait2 {
11+
use Trait1;
12+
public const Constant = 456;
13+
}
14+
?>
15+
--EXPECTF--
16+
Fatal error: Trait2 and Trait1 define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_013.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Conflicting constants in a trait and another trait using it with different finality should result in a fatal error, since this indicates that the code is incompatible.
3+
--FILE--
4+
<?php
5+
6+
trait Trait1 {
7+
public const Constant = 123;
8+
}
9+
10+
trait Trait2 {
11+
use Trait1;
12+
public const Constant = 456;
13+
}
14+
?>
15+
--EXPECTF--
16+
Fatal error: Trait2 and Trait1 define the same constant (Constant). However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_014.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Cannot override a final trait constant in a class derived from the class that uses the trait
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait {
7+
public final const Constant = 123;
8+
}
9+
10+
class ComposingClass {
11+
use TestTrait;
12+
public final const Constant = 123;
13+
}
14+
15+
class DerivedClass extends ComposingClass {
16+
public final const Constant = 456;
17+
}
18+
19+
?>
20+
--EXPECTF--
21+
Fatal error: DerivedClass::Constant cannot override final constant TestTrait::Constant in %s on line %d

Zend/tests/traits/constant_015.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
The same name constant of a trait used in a class that inherits a constant defined in a parent can be defined only if they are compatible.
3+
--FILE--
4+
<?php
5+
6+
trait TestTrait1 {
7+
public final const Constant = 123;
8+
}
9+
10+
class BaseClass1 {
11+
public final const Constant = 123;
12+
}
13+
14+
class DerivedClass1 extends BaseClass1 {
15+
use TestTrait1;
16+
}
17+
18+
trait TestTrait2 {
19+
public final const Constant = 123;
20+
}
21+
22+
class BaseClass2 {
23+
public final const Constant = 456;
24+
}
25+
26+
class DerivedClass2 extends BaseClass2 {
27+
use TestTrait2;
28+
}
29+
30+
?>
31+
--EXPECTF--
32+
Fatal error: BaseClass2 and TestTrait2 define the same constant (Constant) in the composition of DerivedClass2. However, the definition differs and is considered incompatible. Class was composed in %s on line %d

Zend/tests/traits/constant_016.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Compatibility of values of same name trait constants is checked after their constant expressions are evaluated
3+
--FILE--
4+
<?php
5+
6+
define('CONSTANT', 2);
7+
8+
trait TestTrait {
9+
public const Constant = 40 + CONSTANT;
10+
}
11+
12+
class ComposingClass {
13+
use TestTrait;
14+
public const Constant = 42;
15+
}
16+
17+
echo ComposingClass::Constant;
18+
?>
19+
--EXPECTF--
20+
42

0 commit comments

Comments
 (0)