Skip to content

Commit

Permalink
Implement nullsafe ?-> operator
Browse files Browse the repository at this point in the history
  • Loading branch information
iluuu1994 committed Jul 11, 2020
1 parent d5a0370 commit 18c69af
Show file tree
Hide file tree
Showing 45 changed files with 1,593 additions and 523 deletions.
106 changes: 106 additions & 0 deletions Zend/tests/nullsafe_operator/001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
--TEST--
Test basic nullsafe method calls
--FILE--
<?php

class Foo {
function null() {
var_dump('Foo::null()');
return null;
}

function self() {
var_dump('Foo::self()');
return $this;
}
}

var_dump(null?->bar());
var_dump(null?->bar(var_dump('Not executed')));
var_dump(null?->bar()->baz());
var_dump(null?->bar()->baz(var_dump('Not executed')));
var_dump(null?->bar()->baz);
var_dump(null?->bar()::$baz);
var_dump(null?->bar()::baz());

$foo = new Foo();
var_dump($foo->null()?->bar());
var_dump($foo->null()?->bar(var_dump('Not executed')));
var_dump($foo->null()?->bar()->baz());
var_dump($foo->null()?->bar()->baz(var_dump('Not executed')));
var_dump($foo->null()?->bar()->baz);
var_dump($foo->null()?->bar()::$baz);
var_dump($foo->null()?->bar()::baz());

$foo = new Foo();
var_dump($foo?->self(var_dump('Executed'))->null()?->bar());
var_dump($foo?->self(var_dump('Executed'))->null()?->bar(var_dump('Not executed')));
var_dump($foo?->self(var_dump('Executed'))->null()?->bar()->baz());
var_dump($foo?->self(var_dump('Executed'))->null()?->bar()->baz(var_dump('Not executed')));
var_dump($foo?->self(var_dump('Executed'))->null()?->bar()->baz);
var_dump($foo?->self(var_dump('Executed'))->null()?->bar()::$baz);
var_dump($foo?->self(var_dump('Executed'))->null()?->bar()::baz());

var_dump($foo->self(null?->bar())->null());
try {
var_dump($foo?->self()[null?->bar()]);
} catch (Throwable $e) {
var_dump($e->getMessage());
}

?>
--EXPECT--
NULL
NULL
NULL
NULL
NULL
NULL
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(8) "Executed"
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(11) "Foo::self()"
string(11) "Foo::null()"
NULL
string(11) "Foo::self()"
string(38) "Cannot use object of type Foo as array"
42 changes: 42 additions & 0 deletions Zend/tests/nullsafe_operator/002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
Test nullsafe strict type check
--FILE--
<?php

try {
false?->bar();
} catch (Throwable $e) {
var_dump($e->getMessage());
}

try {
[]?->bar();
} catch (Throwable $e) {
var_dump($e->getMessage());
}

try {
(0)?->bar();
} catch (Throwable $e) {
var_dump($e->getMessage());
}

try {
(0.0)?->bar();
} catch (Throwable $e) {
var_dump($e->getMessage());
}

try {
''?->bar();
} catch (Throwable $e) {
var_dump($e->getMessage());
}

?>
--EXPECT--
string(39) "Call to a member function bar() on bool"
string(40) "Call to a member function bar() on array"
string(38) "Call to a member function bar() on int"
string(40) "Call to a member function bar() on float"
string(41) "Call to a member function bar() on string"
66 changes: 66 additions & 0 deletions Zend/tests/nullsafe_operator/003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
--TEST--
Test basic nullsafe property fetching
--FILE--
<?php

class Foo {
public $bar = 'bar';

function qux() {
return 'qux';
}
}

$null = null;
$foo = new Foo();

var_dump(null?->bar);
var_dump(null?->baz);
var_dump(null?->qux());
var_dump(null?->quux());

var_dump((new Foo)?->bar);
var_dump((new Foo)?->baz);
var_dump((new Foo)?->qux());
try {
var_dump((new Foo)?->quux());
} catch (Throwable $e) {
var_dump($e->getMessage());
}

var_dump("{$null?->foo}");
var_dump("{$null?->bar}");
var_dump("{$null?->qux()}");
var_dump("{$null?->quux()}");

var_dump("{$foo?->bar}");
var_dump("{$foo?->baz}");
var_dump("{$foo?->qux()}");
try {
var_dump("{$foo?->quux()}");
} catch (Throwable $e) {
var_dump($e->getMessage());
}

?>
--EXPECTF--
NULL
NULL
NULL
NULL
string(3) "bar"

Warning: Undefined property: Foo::$baz in %s.php on line 20
NULL
string(3) "qux"
string(36) "Call to undefined method Foo::quux()"
string(0) ""
string(0) ""
string(0) ""
string(0) ""
string(3) "bar"

Warning: Undefined property: Foo::$baz in %s.php on line 34
string(0) ""
string(3) "qux"
string(36) "Call to undefined method Foo::quux()"
23 changes: 23 additions & 0 deletions Zend/tests/nullsafe_operator/004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Test nullsafe property assignment
--FILE--
<?php

class Foo {
public $bar;
}

function test(?Foo $foo) {
var_dump($foo?->bar = 'bar');
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
string(3) "bar"
string(3) "bar"
23 changes: 23 additions & 0 deletions Zend/tests/nullsafe_operator/005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Test nullsafe property assignment op
--FILE--
<?php

class Foo {
public $bar = 0;
}

function test(?Foo $foo) {
var_dump($foo?->bar += 1);
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
int(1)
int(1)
29 changes: 29 additions & 0 deletions Zend/tests/nullsafe_operator/006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Test nullsafe property post increment/decrement
--FILE--
<?php

class Foo {
public $bar = 0;
}

function test(?Foo $foo) {
var_dump(++$foo?->bar);
var_dump($foo?->bar);
var_dump(--$foo?->bar);
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
NULL
NULL
int(1)
int(1)
int(0)
int(0)
29 changes: 29 additions & 0 deletions Zend/tests/nullsafe_operator/007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Test nullsafe property pre increment/decrement
--FILE--
<?php

class Foo {
public $bar = 0;
}

function test(?Foo $foo) {
var_dump($foo?->bar++);
var_dump($foo?->bar);
var_dump($foo?->bar--);
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
NULL
NULL
int(0)
int(1)
int(1)
int(0)
23 changes: 23 additions & 0 deletions Zend/tests/nullsafe_operator/008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Test nullsafe property coalesce assignment
--FILE--
<?php

class Foo {
public $bar;
}

function test(?Foo $foo) {
var_dump($foo?->bar ??= 'bar');
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
string(3) "bar"
string(3) "bar"
24 changes: 24 additions & 0 deletions Zend/tests/nullsafe_operator/009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Test fetch nullsafe property by ref
--FILE--
<?php

class Foo {
public $bar;
}

function test(?Foo $foo) {
var_dump($ref = &$foo?->bar);
$ref = 'bar';
var_dump($foo?->bar);
}

test(null);
test(new Foo());

?>
--EXPECT--
NULL
NULL
NULL
string(3) "bar"

0 comments on commit 18c69af

Please sign in to comment.