Skip to content

Commit 21c55c7

Browse files
committed
Extract class constants
1 parent 332393a commit 21c55c7

File tree

1 file changed

+91
-18
lines changed

1 file changed

+91
-18
lines changed

extractor/extract.php

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -435,14 +435,21 @@ private function compareStatementsInNamespace(array $oldStmts, array $newStmts,
435435
throw new \LogicException('Classname changed');
436436
}
437437
$newMethods = array_filter($new->stmts, fn (Node\Stmt $stmt) => $stmt instanceof Node\Stmt\ClassMethod);
438-
[$untouchedStmts, $oldMethodsStmt] = $this->filterStatementsByVersion($old->stmts, $updateFrom);
438+
$newConstants = array_filter($new->stmts, fn (Node\Stmt $stmt) => $stmt instanceof Node\Stmt\ClassConst);
439+
[$untouchedStmts, $oldStmts] = $this->filterStatementsByVersion($old->stmts, $updateFrom);
439440
$oldMethods = [];
440-
foreach ($oldMethodsStmt as $stmt) {
441-
if (!$stmt instanceof Node\Stmt\ClassMethod) {
441+
$oldConstants = [];
442+
foreach ($oldStmts as $stmt) {
443+
if ($stmt instanceof Node\Stmt\ClassMethod) {
444+
$oldMethods[$stmt->name->toLowerString()] = $stmt;
442445
continue;
443446
}
444447

445-
$oldMethods[$stmt->name->toLowerString()] = $stmt;
448+
if ($stmt instanceof Node\Stmt\ClassConst) {
449+
$names = array_map(static fn (Node\Const_ $const) => $const->name->toString(), $stmt->consts);
450+
$oldConstants[implode(',', $names)] = $stmt;
451+
continue;
452+
}
446453
}
447454

448455
if ($old->stmts !== null) {
@@ -467,6 +474,26 @@ private function compareStatementsInNamespace(array $oldStmts, array $newStmts,
467474

468475
// todo has a method been removed?
469476
477+
foreach ($newConstants as $stmt) {
478+
$namesKey = implode(',', array_map(static fn (Node\Const_ $const) => $const->name->toString(), $stmt->consts));
479+
if (!array_key_exists($namesKey, $oldConstants)) {
480+
$stmt->attrGroups[] = new Node\AttributeGroup([
481+
new Node\Attribute(
482+
new Node\Name\FullyQualified('Since'),
483+
[new Node\Arg(new Node\Scalar\String_($updateTo))],
484+
),
485+
]);
486+
$newStmtsToSet[] = $stmt;
487+
continue;
488+
}
489+
490+
foreach ($this->compareConstants($oldConstants[$namesKey], $stmt, $updateTo) as $constantStmt) {
491+
$newStmtsToSet[] = $constantStmt;
492+
}
493+
}
494+
495+
// todo has a constant been removed?
496+
470497
$old->stmts = $newStmtsToSet;
471498
}
472499

@@ -508,49 +535,49 @@ private function compareFunctions(Node\FunctionLike $old, Node\FunctionLike $new
508535
}
509536
}
510537
if ($this->printType($old->getReturnType()) !== $this->printType($new->getReturnType())) {
511-
return $this->functionDiff($old, $new, $updateTo);
538+
return $this->stmtDiff($old, $new, $updateTo);
512539
}
513540
if ($old->returnsByRef() !== $new->returnsByRef()) {
514-
return $this->functionDiff($old, $new, $updateTo);
541+
return $this->stmtDiff($old, $new, $updateTo);
515542
}
516543
if (count($old->getParams()) !== count($new->getParams())) {
517-
return $this->functionDiff($old, $new, $updateTo);
544+
return $this->stmtDiff($old, $new, $updateTo);
518545
}
519546

520547
foreach ($old->getParams() as $i => $oldParam) {
521548
$newParam = $new->getParams()[$i];
522549
if ($this->printType($oldParam->type) !== $this->printType($newParam->type)) {
523-
return $this->functionDiff($old, $new, $updateTo);
550+
return $this->stmtDiff($old, $new, $updateTo);
524551
}
525552
if ($oldParam->byRef !== $newParam->byRef) {
526-
return $this->functionDiff($old, $new, $updateTo);
553+
return $this->stmtDiff($old, $new, $updateTo);
527554
}
528555
if ($oldParam->variadic !== $newParam->variadic) {
529-
return $this->functionDiff($old, $new, $updateTo);
556+
return $this->stmtDiff($old, $new, $updateTo);
530557
}
531558
assert($oldParam->var instanceof Node\Expr\Variable);
532559
assert(is_string($oldParam->var->name));
533560
assert($newParam->var instanceof Node\Expr\Variable);
534561
assert(is_string($newParam->var->name));
535562
if ($oldParam->var->name !== $newParam->var->name) {
536-
return $this->functionDiff($old, $new, $updateTo);
563+
return $this->stmtDiff($old, $new, $updateTo);
537564
}
538565
if (is_null($oldParam->default) !== is_null($newParam->default)) {
539-
return $this->functionDiff($old, $new, $updateTo);
566+
return $this->stmtDiff($old, $new, $updateTo);
540567
}
541568
if ($oldParam->default !== null && $newParam->default !== null) {
542569
if ($this->printer->prettyPrintExpr($oldParam->default) !== $this->printer->prettyPrintExpr($newParam->default)) {
543-
return $this->functionDiff($old, $new, $updateTo);
570+
return $this->stmtDiff($old, $new, $updateTo);
544571
}
545572
}
546573
if ($oldParam->flags !== $newParam->flags) {
547-
return $this->functionDiff($old, $new, $updateTo);
574+
return $this->stmtDiff($old, $new, $updateTo);
548575
}
549576
}
550577

551578
if ($old instanceof Node\Stmt\ClassMethod && $new instanceof Node\Stmt\ClassMethod) {
552579
if ($old->flags !== $new->flags) {
553-
return $this->functionDiff($old, $new, $updateTo);
580+
return $this->stmtDiff($old, $new, $updateTo);
554581
}
555582
}
556583

@@ -596,19 +623,19 @@ private function compareFunctions(Node\FunctionLike $old, Node\FunctionLike $new
596623
}
597624

598625
if ($oldPhpDocParameters !== $newPhpDocParameters) {
599-
return $this->functionDiff($old, $new, $updateTo);
626+
return $this->stmtDiff($old, $new, $updateTo);
600627
}
601628

602629
return [$old];
603630
}
604631

605632
/**
606-
* @template T of Node\FunctionLike
633+
* @template T of Node
607634
* @param T $old
608635
* @param T $new
609636
* @return T[]
610637
*/
611-
private function functionDiff(Node\FunctionLike $old, Node\FunctionLike $new, string $updateTo): array
638+
private function stmtDiff(Node $old, Node $new, string $updateTo): array
612639
{
613640
$args = [new Node\Arg(new Node\Scalar\String_($updateTo))];
614641
$old = clone $old;
@@ -632,6 +659,52 @@ private function functionDiff(Node\FunctionLike $old, Node\FunctionLike $new, st
632659
return [$old, $new];
633660
}
634661

662+
/**
663+
* @return Node\Stmt\ClassConst[]
664+
*/
665+
private function compareConstants(Node\Stmt\ClassConst $old, Node\Stmt\ClassConst $new, string $updateTo): array
666+
{
667+
if ($old->getDocComment() !== $new->getDocComment()) {
668+
return $this->stmtDiff($old, $new, $updateTo);
669+
}
670+
if ($old->flags !== $new->flags) {
671+
return $this->stmtDiff($old, $new, $updateTo);
672+
}
673+
674+
if (count($old->consts) !== count($new->consts)) {
675+
return $this->stmtDiff($old, $new, $updateTo);
676+
}
677+
678+
foreach ($new->consts as $i => $newConst) {
679+
$oldConst = $old->consts[$i];
680+
if ($oldConst->name->toString() !== $newConst->name->toString()) {
681+
return $this->stmtDiff($old, $new, $updateTo);
682+
}
683+
684+
$oldValue = $this->printer->prettyPrintExpr($oldConst->value);
685+
$newValue = $this->printer->prettyPrintExpr($newConst->value);
686+
if ($oldValue !== $newValue) {
687+
return $this->stmtDiff($old, $new, $updateTo);
688+
}
689+
}
690+
691+
$oldType = $old->type;
692+
$newType = $new->type;
693+
if ($oldType !== null) {
694+
if ($newType === null) {
695+
return $this->stmtDiff($old, $new, $updateTo);
696+
}
697+
698+
if ($this->printType($oldType) !== $this->printType($newType)) {
699+
return $this->stmtDiff($old, $new, $updateTo);
700+
}
701+
} elseif ($newType !== null) {
702+
return $this->stmtDiff($old, $new, $updateTo);
703+
}
704+
705+
return [$old];
706+
}
707+
635708
/**
636709
* @param Node\Identifier|Node\Name|Node\ComplexType|null $type
637710
*/

0 commit comments

Comments
 (0)