Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions Zend/tests/friends/anonymous_class.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
--TEST--
Friends: anonymous classes can have friends
--FILE--
<?php

class Bar {
public static function testAccess(object $obj) {
$obj::protectedStatic();
echo "\n";
$obj::privateStatic();
echo "\n";
$obj->protectedInstance();
echo "\n";
$obj->privateInstance();
echo "\n";
$obj->protectedProp = 1;
$obj->privateProp = 2;
var_dump($obj);
var_dump($obj::FIRST);
var_dump($obj::SECOND);
}
}

$obj = new class () {
friend Bar;

protected $protectedProp;
private $privateProp;

protected const FIRST = 1;
private const SECOND = 2;

protected static function protectedStatic() {
echo __METHOD__ . "() called, backtrace:\n";
debug_print_backtrace();
}

private static function privateStatic() {
echo __METHOD__ . "() called, backtrace:\n";
debug_print_backtrace();
}

protected function protectedInstance() {
echo __METHOD__ . "() called, backtrace:\n";
debug_print_backtrace();
}

private function privateInstance() {
echo __METHOD__ . "() called, backtrace:\n";
debug_print_backtrace();
}
};

Bar::testAccess($obj);

?>
--EXPECTF--
class@anonymous%s:%d$0::protectedStatic() called, backtrace:
#0 %s(%d): class@anonymous::protectedStatic()
#1 %s(%d): Bar::testAccess(Object(class@anonymous))

class@anonymous%s:%d$0::privateStatic() called, backtrace:
#0 %s(%d): class@anonymous::privateStatic()
#1 %s(%d): Bar::testAccess(Object(class@anonymous))

class@anonymous%s:%d$0::protectedInstance() called, backtrace:
#0 %s(%d): class@anonymous->protectedInstance()
#1 %s(%d): Bar::testAccess(Object(class@anonymous))

class@anonymous%s:%d$0::privateInstance() called, backtrace:
#0 %s(%d): class@anonymous->privateInstance()
#1 %s(%d): Bar::testAccess(Object(class@anonymous))

object(class@anonymous)#1 (2) {
["protectedProp":protected]=>
int(1)
["privateProp":"class@anonymous":private]=>
int(2)
}
int(1)
int(2)
23 changes: 23 additions & 0 deletions Zend/tests/friends/ast_printing.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Friends: AST printing
--FILE--
<?php

try {
assert(function () {
class Foo {
friend Bar;
}
} && false);
} catch (Error $e) {
echo $e->getMessage();
}

?>
--EXPECT--
assert(function () {
class Foo {
friend Bar;
}

} && false)
48 changes: 48 additions & 0 deletions Zend/tests/friends/clone_access.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--TEST--
Friends: allows access to cloning
--FILE--
<?php

class Foo {
friend Bar;

private function __clone() {
echo __METHOD__ . "() called, backtrace:\n";
debug_print_backtrace();
}

}

class Bar {
public static function testCloneAccess() {
$f = new Foo();
$g = clone $f;
}
}

// Confirm that the presence of a friend does not negate normal visibility
// enforcement for non friends
$f = new Foo();
try {
clone $f;
} catch (Error $e) {
echo $e . "\n";
}

echo "\n\n-----\n\n";

// But friend works
Bar::testCloneAccess();

?>
--EXPECTF--
Error: Call to private method Foo::__clone() from global scope in %s:%d
Stack trace:
#0 {main}


-----

Foo::__clone() called, backtrace:
#0 %s(%d): Foo->__clone()
#1 %s(%d): Bar::testCloneAccess()
12 changes: 12 additions & 0 deletions Zend/tests/friends/compiler_errors/interface_error.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Friends: cannot be used on interfaces
--FILE--
<?php

interface Foo {
friend Bar;
}

?>
--EXPECTF--
Fatal error: Cannot add friends to interfaces. Bar is used in Foo in %s on line %d
13 changes: 13 additions & 0 deletions Zend/tests/friends/compiler_errors/repetition_basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Friends: same friend cannot be used multiple times
--FILE--
<?php

class Foo {
friend Bar;
friend Bar;
}

?>
--EXPECTF--
Fatal error: Cannot add Bar as a friend of Foo multiple times. in %s on line %d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Friends: same friend cannot be used multiple times (case insensitive)
--FILE--
<?php

class Foo {
friend Bar;
friend BAR;
}

?>
--EXPECTF--
Fatal error: Cannot add BAR as a friend of Foo multiple times. in %s on line %d
16 changes: 16 additions & 0 deletions Zend/tests/friends/compiler_errors/repetition_name_resolution.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
Friends: same friend cannot be used multiple times (after name resolution)
--FILE--
<?php

use SomeNamespace\Bar;
use SomeNamespace\Bar as Baz;

class Foo {
friend Bar;
friend Baz;
}

?>
--EXPECTF--
Fatal error: Cannot add SomeNamespace\Bar as a friend of Foo multiple times. in %s on line %d
12 changes: 12 additions & 0 deletions Zend/tests/friends/compiler_errors/reserved_parent.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Friends: 'parent' cannot be used as a friend name
--FILE--
<?php

class Foo {
friend parent;
}

?>
--EXPECTF--
Fatal error: Cannot use "parent" as friend name, as it is reserved in %s on line %d
12 changes: 12 additions & 0 deletions Zend/tests/friends/compiler_errors/reserved_self.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Friends: 'self' cannot be used as a friend name
--FILE--
<?php

class Foo {
friend self;
}

?>
--EXPECTF--
Fatal error: Cannot use "self" as friend name, as it is reserved in %s on line %d
12 changes: 12 additions & 0 deletions Zend/tests/friends/compiler_errors/reserved_static.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Friends: 'static' cannot be used as a friend name
--FILE--
<?php

class Foo {
friend static;
}

?>
--EXPECTF--
Fatal error: Cannot use "static" as friend name, as it is reserved in %s on line %d
12 changes: 12 additions & 0 deletions Zend/tests/friends/compiler_errors/trait_error.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Friends: cannot be used on traits
--FILE--
<?php

trait Foo {
friend Bar;
}

?>
--EXPECTF--
Fatal error: Cannot add friends to traits. Bar is used in Foo in %s on line %d
53 changes: 53 additions & 0 deletions Zend/tests/friends/constant_access.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
--TEST--
Friends: allows access to constants
--FILE--
<?php

class Foo {
friend Bar;

protected const FIRST = 1;
private const SECOND = 2;
}

class Bar {
public static function testConstantAccess() {
var_dump(Foo::FIRST);
var_dump(Foo::SECOND);
}
}

// Confirm that the presence of a friend does not negate normal visibility
// enforcement for non friends
try {
var_dump(Foo::FIRST);
} catch (Error $e) {
echo $e . "\n\n";
}
try {
var_dump(Foo::SECOND);
} catch (Error $e) {
echo $e . "\n\n";
}

echo "\n\n-----\n\n";

// But friend works
Bar::testConstantAccess();

?>
--EXPECTF--
Error: Cannot access protected constant Foo::FIRST in %s:%d
Stack trace:
#0 {main}

Error: Cannot access private constant Foo::SECOND in %s:%d
Stack trace:
#0 {main}



-----

int(1)
int(2)
40 changes: 40 additions & 0 deletions Zend/tests/friends/constant_access_inherited.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
Friends: allows access to inherited non-overridden constants
--FILE--
<?php

class Foo {
friend Bar;

protected const FIRST = 1;
protected const SECOND = 2;
}

class FooChild extends Foo {
protected const SECOND = 3;
}

class Bar {
public static function testConstantAccess() {
var_dump(FooChild::FIRST);

echo "\n";

try {
var_dump(FooChild::SECOND);
} catch (Error $e) {
echo $e . "\n\n";
}
}
}

Bar::testConstantAccess();

?>
--EXPECTF--
int(1)

Error: Cannot access protected constant FooChild::SECOND in %s:%d
Stack trace:
#0 %s(%d): Bar::testConstantAccess()
#1 {main}
Loading
Loading