Skip to content

Commit e219849

Browse files
committed
MFH
2 parents f25b9d2 + ad91d48 commit e219849

39 files changed

+1089
-128
lines changed

ChangeLog.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ XP Compiler ChangeLog
88
its length. Includes support for static and instance methods as well as
99
indirect references like `$closure(...)` and `self::{$expression}(...)`,
1010
see https://wiki.php.net/rfc/first_class_callable_syntax
11+
12+
## 6.6.0 / 2021-07-10
13+
14+
* Emit null-coalesce operator as `$a ?? $a= expression` instead of as
15+
`$a= $a ?? expression`, saving one assignment operation for non-null
16+
case. Applies to PHP 7.0, 7.1 and 7.2.
17+
(@thekid)
18+
* Removed conditional checks for PHP 8.1 with native enum support, all
19+
releases and builds available on CI systems now contain it.
20+
(@thekid)
21+
* Increased test coverage significantly (to more than 90%), especially
22+
for classes used by the compiler command line.
1123
(@thekid)
1224

1325
## 6.5.0 / 2021-05-22

src/main/php/lang/ast/Compiled.class.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ public function write($bytes) {
5555
$this->compiled.= $bytes;
5656
}
5757

58-
/** @return void */
58+
/** @codeCoverageIgnore */
5959
public function flush() {
6060
// NOOP
6161
}
6262

63-
/** @return void */
63+
/** @codeCoverageIgnore */
6464
public function close() {
6565
// NOOP
6666
}
@@ -77,12 +77,6 @@ public function stream_read($count) {
7777
return $chunk;
7878
}
7979

80-
/** @return [:var] */
81-
public function url_stat($path) {
82-
$opened= substr($path, strpos($path, '://') + 3);
83-
return ['size' => self::$source[$opened]->getResourceAsStream($opened)->size()];
84-
}
85-
8680
/** @return [:var] */
8781
public function stream_stat() {
8882
return ['size' => strlen($this->compiled)];

src/main/php/lang/ast/CompilingClassloader.class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ public function loadClass0($class) {
166166
try {
167167
include($this->version.'://'.$uri);
168168
} catch (ClassLoadingException $e) {
169-
unset(\xp::$cl[$class]);
170-
throw $e;
169+
unset(\xp::$cl[$class]); // @codeCoverageIgnore
170+
throw $e; // @codeCoverageIgnore
171171
} catch (\Throwable $e) {
172172
unset(\xp::$cl[$class]);
173173
throw new ClassFormatException('Compiler error: '.$e->getMessage(), $e);

src/main/php/lang/ast/emit/PHP.class.php

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -364,72 +364,30 @@ protected function emitLambda($result, $lambda) {
364364
}
365365

366366
protected function emitEnumCase($result, $case) {
367-
$result->out->write('public static $'.$case->name.';');
367+
$result->out->write('case '.$case->name);
368+
if ($case->expression) {
369+
$result->out->write('=');
370+
$this->emitOne($result, $case->expression);
371+
}
372+
$result->out->write(';');
368373
}
369374

370375
protected function emitEnum($result, $enum) {
371376
array_unshift($result->type, $enum);
372377
array_unshift($result->meta, []);
373378
$result->locals= [[], []];
374379

375-
$result->out->write('final class '.$this->declaration($enum->name).' implements \\'.($enum->base ? 'BackedEnum' : 'UnitEnum'));
376-
$enum->implements && $result->out->write(', '.implode(', ', $enum->implements));
380+
$result->out->write('enum '.$this->declaration($enum->name));
381+
$enum->base && $result->out->write(':'.$enum->base);
382+
$enum->implements && $result->out->write(' implements '.implode(', ', $enum->implements));
377383
$result->out->write('{');
378384

379-
$cases= [];
380385
foreach ($enum->body as $member) {
381-
if ($member->is('enumcase')) $cases[]= $member;
382386
$this->emitOne($result, $member);
383387
}
384388

385-
// Constructors
386-
if ($enum->base) {
387-
$result->out->write('public $name, $value;');
388-
$result->out->write('private static $values= [];');
389-
$result->out->write('private function __construct($name, $value) {
390-
$this->name= $name;
391-
$this->value= $value;
392-
self::$values[$value]= $this;
393-
}');
394-
$result->out->write('public static function tryFrom($value) {
395-
return self::$values[$value] ?? null;
396-
}');
397-
$result->out->write('public static function from($value) {
398-
if ($r= self::$values[$value] ?? null) return $r;
399-
throw new \Error(\util\Objects::stringOf($value)." is not a valid backing value for enum \"".self::class."\"");
400-
}');
401-
} else {
402-
$result->out->write('public $name;');
403-
$result->out->write('private function __construct($name) {
404-
$this->name= $name;
405-
}');
406-
}
407-
408-
// Prevent cloning enums
409-
$result->out->write('public function __clone() {
410-
throw new \Error("Trying to clone an uncloneable object of class ".self::class);
411-
}');
412-
413-
// Enum cases
414-
$result->out->write('public static function cases() { return [');
415-
foreach ($cases as $case) {
416-
$result->out->write('self::$'.$case->name.', ');
417-
}
418-
$result->out->write(']; }');
419-
420389
// Initializations
421390
$result->out->write('static function __init() {');
422-
if ($enum->base) {
423-
foreach ($cases as $case) {
424-
$result->out->write('self::$'.$case->name.'= new self("'.$case->name.'", ');
425-
$this->emitOne($result, $case->expression);
426-
$result->out->write(');');
427-
}
428-
} else {
429-
foreach ($cases as $case) {
430-
$result->out->write('self::$'.$case->name.'= new self("'.$case->name.'");');
431-
}
432-
}
433391
$this->emitInitializations($result, $result->locals[0]);
434392
$this->emitMeta($result, $enum->name, $enum->annotations, $enum->comment);
435393
$result->out->write('}} '.$enum->name.'::__init();');

src/main/php/lang/ast/emit/PHP70.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
class PHP70 extends PHP {
1313
use OmitPropertyTypes, OmitConstModifiers;
14-
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteMultiCatch, RewriteClassOnObjects, RewriteExplicitOctals;
14+
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteMultiCatch, RewriteClassOnObjects, RewriteExplicitOctals, RewriteEnums;
1515

1616
/** Sets up type => literal mappings */
1717
public function __construct() {

src/main/php/lang/ast/emit/PHP71.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
class PHP71 extends PHP {
1111
use OmitPropertyTypes, CallablesAsClosures;
12-
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals;
12+
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals, RewriteEnums;
1313

1414
/** Sets up type => literal mappings */
1515
public function __construct() {

src/main/php/lang/ast/emit/PHP72.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
class PHP72 extends PHP {
1111
use OmitPropertyTypes, CallablesAsClosures;
12-
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals;
12+
use RewriteNullCoalesceAssignment, RewriteLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals, RewriteEnums;
1313

1414
/** Sets up type => literal mappings */
1515
public function __construct() {

src/main/php/lang/ast/emit/PHP74.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* @see https://wiki.php.net/rfc#php_74
99
*/
1010
class PHP74 extends PHP {
11-
use RewriteBlockLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals, CallablesAsClosures;
11+
use RewriteBlockLambdaExpressions, RewriteClassOnObjects, RewriteExplicitOctals, RewriteEnums, CallablesAsClosures;
1212

1313
/** Sets up type => literal mappings */
1414
public function __construct() {

src/main/php/lang/ast/emit/PHP80.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @see https://wiki.php.net/rfc#php_80
1010
*/
1111
class PHP80 extends PHP {
12-
use RewriteBlockLambdaExpressions, RewriteExplicitOctals, CallablesAsClosures;
12+
use RewriteBlockLambdaExpressions, RewriteExplicitOctals, RewriteEnums, CallablesAsClosures;
1313

1414
/** Sets up type => literal mappings */
1515
public function __construct() {

src/main/php/lang/ast/emit/PHP81.class.php

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,51 +40,6 @@ protected function emitArguments($result, $arguments) {
4040
}
4141
}
4242

43-
protected function emitEnumCase($result, $case) {
44-
45-
// TODO: Once enum PR is merged, remove this conditional and refactor the
46-
// code into a `RewriteEnums` trait to be included for all other versions
47-
if (Type::$ENUMS) {
48-
$result->out->write('case '.$case->name);
49-
if ($case->expression) {
50-
$result->out->write('=');
51-
$this->emitOne($result, $case->expression);
52-
}
53-
$result->out->write(';');
54-
} else {
55-
parent::emitEnumCase($result, $case);
56-
}
57-
}
58-
59-
protected function emitEnum($result, $enum) {
60-
61-
// TODO: Once enum PR is merged, remove this conditional and refactor the
62-
// code into a `RewriteEnums` trait to be included for all other versions
63-
if (Type::$ENUMS) {
64-
array_unshift($result->type, $enum);
65-
array_unshift($result->meta, []);
66-
$result->locals= [[], []];
67-
68-
$result->out->write('enum '.$this->declaration($enum->name));
69-
$enum->base && $result->out->write(':'.$enum->base);
70-
$enum->implements && $result->out->write(' implements '.implode(', ', $enum->implements));
71-
$result->out->write('{');
72-
73-
foreach ($enum->body as $member) {
74-
$this->emitOne($result, $member);
75-
}
76-
77-
// Initializations
78-
$result->out->write('static function __init() {');
79-
$this->emitInitializations($result, $result->locals[0]);
80-
$this->emitMeta($result, $enum->name, $enum->annotations, $enum->comment);
81-
$result->out->write('}} '.$enum->name.'::__init();');
82-
array_shift($result->type);
83-
} else {
84-
parent::emitEnum($result, $enum);
85-
}
86-
}
87-
8843
protected function emitNew($result, $new) {
8944
if ($new->type instanceof Node) {
9045
$result->out->write('new (');

0 commit comments

Comments
 (0)