/hphp/test/quick/fsc.php
https://github.com/tstarling/hiphop-php · PHP · 481 lines · 445 code · 11 blank · 25 comment · 0 complexity · 2475a8f9a20260aa1cfef0881943e579 MD5 · raw file
- <?php
- error_reporting(-1);
- class A {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- }
- class B extends A {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public function doFoo() {
- $this->foo(); // B B B
- B::foo(); // B B B
- C::foo(); // C C (Zend outputs: C B B) (Rule 1)
- D::foo(); // D D (Zend outputs: D B B) (Rule 1)
- F::foo(); // F F (Zend outputs: F B B) (Rule 1)
- G::foo(); // G G (Zend outputs: G B B) (Rule 1)
- H::foo(); // H H (Zend outputs: H B B) (Rule 1)
- parent::foo(); // A B B
- self::foo(); // B B B
- static::foo(); // B B B
- echo "****************\n";
- }
- public function doBar() {
- $this->bar(); // B B
- B::bar(); // B B
- C::bar(); // C C
- D::bar(); // D D
- F::bar(); // F F
- G::bar(); // G G
- H::bar(); // H H
- parent::bar(); // A B
- self::bar(); // B B
- static::bar(); // B B
- echo "****************\n";
- }
- }
- class C extends B {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- /**
- * Zend's implementation of call_user_func() and forward_static_call() has
- * a few corner cases where its behavior is strictly incorrect. HipHop will
- * match Zend's behavior except for cases that violate one of the following
- * invariants:
- * 1) If the current instance ($this) is non-null, the class of the current
- * instance must be the same or a descendent of the class enclosing the
- * current method. The PHP group is in the process of depracating this
- * behavior. HipHop explicitly lists this in the inconsistencies doc.
- * 2) If the current instance ($this) is non-null, the class of the current
- * instance must be the same as the current late bound class (aka the
- * "called class"). This invariant is stated explicitly in Zend PHP's
- * documentation: "In non-static contexts, the called class will be the
- * class of the object instance."
- * 3) Normal style calls and call_user_func style calls should produce
- * consistent results aside from any exceptions mentioned in Zend PHP's
- * documentation. Therefore, "B::foo()" and "call_user_func('B::foo')"
- * and "call_user_func(array('B', 'foo'))" should all produce consistent
- * results.
- * 4) call_user_func() and forward_static_call() must never forward the
- * caller's late bound class to the callee if the late bound class is
- * not the same or a descendent of the class enclosing the method.
- * Zend's implementation of forward_static_call contains a check for
- * this, implying intent to uphold this invariant.
- */
- public function testFoo1() {
- echo "############# testFoo1 ##############\n";
- B::foo(); // B D D
- C::foo(); // C D D
- D::foo(); // D D D
- F::foo(); // F F (Zend: F D D) (Rule 1)
- G::foo(); // G G (Zend: G D D) (Rule 1)
- H::foo(); // H H (Zend: H D D) (Rule 1)
- parent::foo(); // B D D
- self::foo(); // C D D
- static::foo(); // D D D
- echo "****************\n";
- forward_static_call(array('B','foo')); // B D D
- forward_static_call(array('C','foo')); // C D D
- forward_static_call(array('D','foo')); // D D D
- forward_static_call(array('F','foo')); // F F
- forward_static_call(array('G','foo')); // G G
- forward_static_call(array('H','foo')); // H H
- forward_static_call(array('parent','foo')); // B D D
- forward_static_call(array('self','foo')); // C D D
- forward_static_call(array('static','foo')); // D D D
- echo "****************\n";
- forward_static_call('B::foo'); // B D D
- forward_static_call('C::foo'); // C D D
- forward_static_call('D::foo'); // D D D
- forward_static_call('F::foo'); // F F
- forward_static_call('G::foo'); // G G
- forward_static_call('H::foo'); // H H
- forward_static_call('parent::foo'); // B D D
- forward_static_call('self::foo'); // C D D
- forward_static_call('static::foo'); // D D D
- echo "****************\n";
- forward_static_call(array('B','B::foo')); // B D D
- forward_static_call(array('B','C::foo')); // warning
- forward_static_call(array('B','D::foo')); // warning
- forward_static_call(array('B','F::foo')); // warning
- forward_static_call(array('B','G::foo')); // warning
- forward_static_call(array('B','H::foo')); // warning
- forward_static_call(array('B','parent::foo')); // A D D
- forward_static_call(array('B','self::foo')); // B D D
- forward_static_call(array('B','static::foo')); // warning
- echo "****************\n";
- forward_static_call(array('G','B::foo')); // warning
- forward_static_call(array('G','C::foo')); // warning
- forward_static_call(array('G','D::foo')); // warning
- forward_static_call(array('G','F::foo')); // F F
- forward_static_call(array('G','G::foo')); // G G
- forward_static_call(array('G','H::foo')); // warning
- forward_static_call(array('G','parent::foo')); // F F (Zend: F D D) (Rule 1)
- forward_static_call(array('G','self::foo')); // G G (Zend: G D D) (Rule 1)
- forward_static_call(array('G','static::foo')); // warning
- echo "****************\n";
- $b = new B;
- forward_static_call(array($b,'foo')); // B B B (Zend: B D B) (Rule 2)
- forward_static_call(array($b,'B::foo')); // B B B (Zend: B D B) (Rule 2)
- forward_static_call(array($b,'C::foo')); // warning
- forward_static_call(array($b,'D::foo')); // warning
- forward_static_call(array($b,'F::foo')); // warning
- forward_static_call(array($b,'G::foo')); // warning
- forward_static_call(array($b,'H::foo')); // warning
- forward_static_call(array($b,'parent::foo')); // A B B (Zend: A D B) (Rule2)
- forward_static_call(array($b,'self::foo')); // B B B (Zend: B D B) (Rule2)
- forward_static_call(array($b,'static::foo')); // warning
- echo "****************\n";
- $g = new G;
- forward_static_call(array($g,'foo')); // G G G
- forward_static_call(array($g,'B::foo')); // warning
- forward_static_call(array($g,'C::foo')); // warning
- forward_static_call(array($g,'D::foo')); // warning
- forward_static_call(array($g,'F::foo')); // F G G
- forward_static_call(array($g,'G::foo')); // G G G
- forward_static_call(array($g,'H::foo')); // warning
- forward_static_call(array($g,'parent::foo')); // F G G
- forward_static_call(array($g,'self::foo')); // G G G
- forward_static_call(array($g,'static::foo')); // warning
- echo "****************\n";
- }
- public static function testFoo2() {
- echo "############# testFoo2 ##############\n";
- B::foo(); // B B
- C::foo(); // C C
- D::foo(); // D D
- F::foo(); // F F
- G::foo(); // G G
- H::foo(); // H H
- parent::foo(); // B D
- self::foo(); // C D
- static::foo(); // D D
- echo "****************\n";
- forward_static_call(array('B','foo')); // B D
- forward_static_call(array('C','foo')); // C D
- forward_static_call(array('D','foo')); // D D
- forward_static_call(array('F','foo')); // F F
- forward_static_call(array('G','foo')); // G G
- forward_static_call(array('H','foo')); // H H
- forward_static_call(array('parent','foo')); // B D
- forward_static_call(array('self','foo')); // C D
- forward_static_call(array('static','foo')); // D D
- echo "****************\n";
- forward_static_call('B::foo'); // B D
- forward_static_call('C::foo'); // C D
- forward_static_call('D::foo'); // D D
- forward_static_call('F::foo'); // F F
- forward_static_call('G::foo'); // G G
- forward_static_call('H::foo'); // H H
- forward_static_call('parent::foo'); // B D
- forward_static_call('self::foo'); // C D
- forward_static_call('static::foo'); // D D
- echo "****************\n";
- forward_static_call(array('B','B::foo')); // B D
- forward_static_call(array('B','C::foo')); // warning
- forward_static_call(array('B','D::foo')); // warning
- forward_static_call(array('B','F::foo')); // warning
- forward_static_call(array('B','G::foo')); // warning
- forward_static_call(array('B','H::foo')); // warning
- forward_static_call(array('B','parent::foo')); // A D
- forward_static_call(array('B','self::foo')); // B D
- forward_static_call(array('B','static::foo')); // warning
- echo "****************\n";
- forward_static_call(array('G','B::foo')); // warning
- forward_static_call(array('G','C::foo')); // warning
- forward_static_call(array('G','D::foo')); // warning
- forward_static_call(array('G','F::foo')); // F F
- forward_static_call(array('G','G::foo')); // G G
- forward_static_call(array('G','H::foo')); // warning
- forward_static_call(array('G','parent::foo')); // F F (Zend: F D) (Rule 4)
- forward_static_call(array('G','self::foo')); // G G (Zend: G D) (Rule 4)
- forward_static_call(array('G','static::foo'));
- echo "****************\n";
- $b = new B;
- forward_static_call(array($b,'foo')); // B B B
- forward_static_call(array($b,'B::foo')); // B B B
- forward_static_call(array($b,'C::foo')); // warning
- forward_static_call(array($b,'D::foo')); // warning
- forward_static_call(array($b,'F::foo')); // warning
- forward_static_call(array($b,'G::foo')); // warning
- forward_static_call(array($b,'H::foo')); // warning
- forward_static_call(array($b,'parent::foo')); // A B B
- forward_static_call(array($b,'self::foo')); // B B B
- forward_static_call(array($b,'static::foo')); // warning
- echo "****************\n";
- $g = new G;
- forward_static_call(array($g,'foo')); // G G G
- forward_static_call(array($g,'B::foo')); // warning
- forward_static_call(array($g,'C::foo')); // warning
- forward_static_call(array($g,'D::foo')); // warning
- forward_static_call(array($g,'F::foo')); // F G G
- forward_static_call(array($g,'G::foo')); // G G G
- forward_static_call(array($g,'H::foo')); // warning
- forward_static_call(array($g,'parent::foo')); // F G G
- forward_static_call(array($g,'self::foo')); // G G G
- forward_static_call(array($g,'static::foo')); // warning
- echo "****************\n";
- }
- public function testBar1() {
- echo "############# testBar1 ##############\n";
- B::bar(); // B B
- C::bar(); // C C
- D::bar(); // D D
- F::bar(); // F F
- G::bar(); // G G
- H::bar(); // H H
- parent::bar(); // B D
- self::bar(); // C D
- static::bar(); // D D
- echo "****************\n";
- forward_static_call(array('B','bar')); // B D
- forward_static_call(array('C','bar')); // C D
- forward_static_call(array('D','bar')); // D D
- forward_static_call(array('F','bar')); // F F
- forward_static_call(array('G','bar')); // G G
- forward_static_call(array('H','bar')); // H H
- forward_static_call(array('parent','bar')); // B D
- forward_static_call(array('self','bar')); // C D
- forward_static_call(array('static','bar')); // D D
- echo "****************\n";
- forward_static_call('B::bar'); // B D
- forward_static_call('C::bar'); // C D
- forward_static_call('D::bar'); // D D
- forward_static_call('F::bar'); // F F
- forward_static_call('G::bar'); // G G
- forward_static_call('H::bar'); // H H
- forward_static_call('parent::bar'); // B D
- forward_static_call('self::bar'); // C D
- forward_static_call('static::bar'); // D D
- echo "****************\n";
- forward_static_call(array('B','B::bar')); // B D
- forward_static_call(array('B','C::bar')); // warning
- forward_static_call(array('B','D::bar')); // warning
- forward_static_call(array('B','F::bar')); // warning
- forward_static_call(array('B','G::bar')); // warning
- forward_static_call(array('B','H::bar')); // warning
- forward_static_call(array('B','parent::bar')); // A D
- forward_static_call(array('B','self::bar')); // B D
- forward_static_call(array('B','static::bar')); // warning
- echo "****************\n";
- forward_static_call(array('G','B::bar'));
- forward_static_call(array('G','C::bar'));
- forward_static_call(array('G','D::bar'));
- forward_static_call(array('G','F::bar')); // F F
- forward_static_call(array('G','G::bar')); // G G
- forward_static_call(array('G','H::bar'));
- forward_static_call(array('G','parent::bar')); // F F (Zend: F D) (Rule 4)
- forward_static_call(array('G','self::bar')); // G G (Zend: G D) (Rule 4)
- forward_static_call(array('G','static::bar'));
- echo "****************\n";
- $b = new B;
- forward_static_call(array($b,'bar')); // B D
- forward_static_call(array($b,'B::bar')); // B D
- forward_static_call(array($b,'C::bar')); // warning
- forward_static_call(array($b,'D::bar')); // warning
- forward_static_call(array($b,'F::bar')); // warning
- forward_static_call(array($b,'G::bar')); // warning
- forward_static_call(array($b,'H::bar')); // warning
- forward_static_call(array($b,'parent::bar')); // A D
- forward_static_call(array($b,'self::bar')); // B D
- forward_static_call(array($b,'static::bar')); // warning
- echo "****************\n";
- $g = new G;
- forward_static_call(array($g,'bar')); // G G
- forward_static_call(array($g,'B::bar')); // warning
- forward_static_call(array($g,'C::bar')); // warning
- forward_static_call(array($g,'D::bar')); // warning
- forward_static_call(array($g,'F::bar')); // F G
- forward_static_call(array($g,'G::bar')); // G G
- forward_static_call(array($g,'H::bar')); // warning
- forward_static_call(array($g,'parent::bar')); // F G
- forward_static_call(array($g,'self::bar')); // G G
- forward_static_call(array($g,'static::bar')); // warning
- echo "****************\n";
- }
- public static function testBar2() {
- echo "############# testBar2 ##############\n";
- B::bar(); // B B
- C::bar(); // C C
- D::bar(); // D D
- F::bar(); // F F
- G::bar(); // G G
- H::bar(); // H H
- parent::bar(); // B D
- self::bar(); // C D
- static::bar(); // D D
- echo "****************\n";
- forward_static_call(array('B','bar')); // B D
- forward_static_call(array('C','bar')); // C D
- forward_static_call(array('D','bar')); // D D
- forward_static_call(array('F','bar')); // F F
- forward_static_call(array('G','bar')); // G G
- forward_static_call(array('H','bar')); // H H
- forward_static_call(array('parent','bar')); // B D
- forward_static_call(array('self','bar')); // C D
- forward_static_call(array('static','bar')); // D D
- echo "****************\n";
- forward_static_call('B::bar'); // B D
- forward_static_call('C::bar'); // C D
- forward_static_call('D::bar'); // D D
- forward_static_call('F::bar'); // F F
- forward_static_call('G::bar'); // G G
- forward_static_call('H::bar'); // H H
- forward_static_call('parent::bar'); // B D
- forward_static_call('self::bar'); // C D
- forward_static_call('static::bar'); // D D
- echo "****************\n";
- forward_static_call(array('B','B::bar')); // B D
- forward_static_call(array('B','C::bar')); // warning
- forward_static_call(array('B','D::bar')); // warning
- forward_static_call(array('B','F::bar')); // warning
- forward_static_call(array('B','G::bar')); // warning
- forward_static_call(array('B','H::bar')); // warning
- forward_static_call(array('B','parent::bar')); // A D
- forward_static_call(array('B','self::bar')); // B D
- forward_static_call(array('B','static::bar')); // warning
- echo "****************\n";
- forward_static_call(array('G','B::bar'));
- forward_static_call(array('G','C::bar'));
- forward_static_call(array('G','D::bar'));
- forward_static_call(array('G','F::bar')); // F F
- forward_static_call(array('G','G::bar')); // G G
- forward_static_call(array('G','H::bar'));
- forward_static_call(array('G','parent::bar')); // F F (Zend: F D) (Rule 4)
- forward_static_call(array('G','self::bar')); // G G (Zend: G D) (Rule 4)
- forward_static_call(array('G','static::bar'));
- echo "****************\n";
- $b = new B;
- forward_static_call(array($b,'bar')); // B D
- forward_static_call(array($b,'B::bar')); // B D
- forward_static_call(array($b,'C::bar'));
- forward_static_call(array($b,'D::bar'));
- forward_static_call(array($b,'F::bar'));
- forward_static_call(array($b,'G::bar'));
- forward_static_call(array($b,'H::bar'));
- forward_static_call(array($b,'parent::bar')); // A D
- forward_static_call(array($b,'self::bar')); // B D
- forward_static_call(array($b,'static::bar'));
- echo "****************\n";
- $g = new G;
- forward_static_call(array($g,'bar')); // G G
- forward_static_call(array($g,'B::bar')); // warning
- forward_static_call(array($g,'C::bar')); // warning
- forward_static_call(array($g,'D::bar')); // warning
- forward_static_call(array($g,'F::bar')); // F G
- forward_static_call(array($g,'G::bar')); // G G
- forward_static_call(array($g,'H::bar')); // warning
- forward_static_call(array($g,'parent::bar')); // F G
- forward_static_call(array($g,'self::bar')); // G G
- forward_static_call(array($g,'static::bar')); // warning
- echo "****************\n";
- }
- }
- class D extends C {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- }
- class F {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- }
- class G extends F {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public function doFoo() {
- $this->foo(); // G G G
- B::foo(); // B B (Zend: B G G) (Rule 1)
- C::foo(); // C C (Zend: C G G) (Rule 1)
- D::foo(); // D D (Zend: D G G) (Rule 1)
- F::foo(); // F G G
- G::foo(); // G G G
- H::foo(); // H H (Zend: H G G) (Rule 1)
- parent::foo(); // F G G
- self::foo(); // G G G
- static::foo(); // G G G
- echo "****************\n";
- }
- public function doBar() {
- $this->bar(); // G G
- B::bar(); // B B
- C::bar(); // C C
- D::bar(); // D D
- F::bar(); // F F
- G::bar(); // G G
- H::bar(); // H H
- parent::bar(); // F G
- self::bar(); // G G
- static::bar(); // G G
- echo "****************\n";
- }
- }
- class H extends G {
- public function foo() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- public static function bar() {
- echo __CLASS__ . ' ' . get_called_class() . ' ' .
- (isset($this) ? get_class($this) : '') . "\n";
- }
- }
- $d = new D;
- $d->testFoo1();
- D::testFoo2();
- $d->testBar1();
- D::testBar2();
- $b = new B;
- $g = new G;
- echo "############# doFoo ##############\n";
- $b->doFoo();
- $g->doFoo();
- echo "############# doBar ##############\n";
- $b->doBar();
- $g->doBar();