Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / psy / psysh / src / CodeCleaner / ValidConstantPass.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2018 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\Expr;
16 use PhpParser\Node\Expr\ClassConstFetch;
17 use PhpParser\Node\Expr\ConstFetch;
18 use PhpParser\Node\Identifier;
19 use Psy\Exception\FatalErrorException;
20
21 /**
22  * Validate that namespaced constant references will succeed.
23  *
24  * This pass throws a FatalErrorException rather than letting PHP run
25  * headfirst into a real fatal error and die.
26  *
27  * @todo Detect constants defined in the current code snippet?
28  *       ... Might not be worth it, since it would need to both be defining and
29  *       referencing a namespaced constant, which doesn't seem like that big of
30  *       a target for failure
31  */
32 class ValidConstantPass extends NamespaceAwarePass
33 {
34     /**
35      * Validate that namespaced constant references will succeed.
36      *
37      * Note that this does not (yet) detect constants defined in the current code
38      * snippet. It won't happen very often, so we'll punt for now.
39      *
40      * @throws FatalErrorException if a constant reference is not defined
41      *
42      * @param Node $node
43      */
44     public function leaveNode(Node $node)
45     {
46         if ($node instanceof ConstFetch && \count($node->name->parts) > 1) {
47             $name = $this->getFullyQualifiedName($node->name);
48             if (!\defined($name)) {
49                 $msg = \sprintf('Undefined constant %s', $name);
50                 throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine());
51             }
52         } elseif ($node instanceof ClassConstFetch) {
53             $this->validateClassConstFetchExpression($node);
54         }
55     }
56
57     /**
58      * Validate a class constant fetch expression.
59      *
60      * @throws FatalErrorException if a class constant is not defined
61      *
62      * @param ClassConstFetch $stmt
63      */
64     protected function validateClassConstFetchExpression(ClassConstFetch $stmt)
65     {
66         // For PHP Parser 4.x
67         $constName = $stmt->name instanceof Identifier ? $stmt->name->toString() : $stmt->name;
68
69         // give the `class` pseudo-constant a pass
70         if ($constName === 'class') {
71             return;
72         }
73
74         // if class name is an expression, give it a pass for now
75         if (!$stmt->class instanceof Expr) {
76             $className = $this->getFullyQualifiedName($stmt->class);
77
78             // if the class doesn't exist, don't throw an exception… it might be
79             // defined in the same line it's used or something stupid like that.
80             if (\class_exists($className) || \interface_exists($className)) {
81                 $refl = new \ReflectionClass($className);
82                 if (!$refl->hasConstant($constName)) {
83                     $constType = \class_exists($className) ? 'Class' : 'Interface';
84                     $msg = \sprintf('%s constant \'%s::%s\' not found', $constType, $className, $constName);
85                     throw new FatalErrorException($msg, 0, E_ERROR, null, $stmt->getLine());
86                 }
87             }
88         }
89     }
90 }