Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of Psy Shell.
5
 *
6
 * (c) 2012-2022 Justin Hileman
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Psy\CodeCleaner;
13
 
14
use PhpParser\Node;
15
use PhpParser\Node\Stmt\Class_;
16
use PhpParser\Node\Stmt\ClassMethod;
17
use Psy\Exception\FatalErrorException;
18
 
19
/**
20
 * The abstract class pass handles abstract classes and methods, complaining if there are too few or too many of either.
21
 */
22
class AbstractClassPass extends CodeCleanerPass
23
{
24
    private $class;
25
    private $abstractMethods;
26
 
27
    /**
28
     * @throws FatalErrorException if the node is an abstract function with a body
29
     *
30
     * @param Node $node
31
     *
32
     * @return int|Node|null Replacement node (or special return value)
33
     */
34
    public function enterNode(Node $node)
35
    {
36
        if ($node instanceof Class_) {
37
            $this->class = $node;
38
            $this->abstractMethods = [];
39
        } elseif ($node instanceof ClassMethod) {
40
            if ($node->isAbstract()) {
41
                $name = \sprintf('%s::%s', $this->class->name, $node->name);
42
                $this->abstractMethods[] = $name;
43
 
44
                if ($node->stmts !== null) {
45
                    $msg = \sprintf('Abstract function %s cannot contain body', $name);
46
                    throw new FatalErrorException($msg, 0, \E_ERROR, null, $node->getLine());
47
                }
48
            }
49
        }
50
    }
51
 
52
    /**
53
     * @throws FatalErrorException if the node is a non-abstract class with abstract methods
54
     *
55
     * @param Node $node
56
     *
57
     * @return int|Node|Node[]|null Replacement node (or special return value)
58
     */
59
    public function leaveNode(Node $node)
60
    {
61
        if ($node instanceof Class_) {
62
            $count = \count($this->abstractMethods);
63
            if ($count > 0 && !$node->isAbstract()) {
64
                $msg = \sprintf(
65
                    'Class %s contains %d abstract method%s must therefore be declared abstract or implement the remaining methods (%s)',
66
                    $node->name,
67
                    $count,
68
                    ($count === 1) ? '' : 's',
69
                    \implode(', ', $this->abstractMethods)
70
                );
71
                throw new FatalErrorException($msg, 0, \E_ERROR, null, $node->getLine());
72
            }
73
        }
74
    }
75
}