PhpMigration\Changes\v5dot6\IncompPropertyArray::leaveNode PHP Method

leaveNode() public method

public leaveNode ( $node )
    public function leaveNode($node)
    {
        /**
         * {Description}
         * Array keys won't be overwritten when defining an array as a property
         * of a class via an array literal
         *
         * Previously, arrays declared as class properties which mixed explicit
         * and implicit keys could have array elements silently overwritten if
         * an explicit key was the same as a sequential implicit key. For
         * example:
         *
         * {Reference}
         * http://php.net/manual/en/migration56.incompatible.php#migration56.incompatible.array-keys
         */
        if ($node instanceof Stmt\Class_) {
            $array_list = [];
            $const_table = [];
            // Gather all array property, save class const
            foreach ($node->stmts as $stmt) {
                if ($stmt instanceof Stmt\Property) {
                    foreach ($stmt->props as $prop) {
                        if ($prop instanceof Stmt\PropertyProperty && $prop->default instanceof Expr\Array_) {
                            $array_list[] = $prop->default;
                        }
                    }
                } elseif ($stmt instanceof Stmt\ClassConst) {
                    foreach ($stmt->consts as $const) {
                        if ($const->value instanceof Scalar) {
                            $const_table['self::' . $const->name] = $const->value->value;
                        }
                    }
                }
            }
            // Check keys in array
            foreach ($array_list as $arr) {
                // Emulate array key initialization
                $keylist = [];
                $has = ['scalar' => false, 'const' => false, 'null' => false, 'unfetched' => false];
                $counter = 0;
                foreach ($arr->items as $item) {
                    if ($item->key instanceof Expr\ClassConstFetch) {
                        $has['const'] = true;
                        // Try to fetch const value
                        $const_name = $item->key->class . '::' . $item->key->name;
                        if (isset($const_table[$const_name])) {
                            $keylist[] = 'V:' . $const_table[$const_name];
                        } else {
                            $has['unfetched'] = true;
                            $keylist[] = 'C:' . $const_name;
                        }
                    } elseif ($item->key instanceof Expr\ConstFetch) {
                        $has['const'] = true;
                        $has['unfetched'] = true;
                        $keylist[] = 'C:' . $item->key->name->toString();
                    } elseif (is_null($item->key)) {
                        $has['null'] = true;
                        $keylist[] = 'N:' . $counter++;
                    } else {
                        $has['scalar'] = true;
                        $keylist[] = 'V:' . $item->key->value;
                    }
                }
                $has['duplicated'] = count($keylist) != count(array_unique($keylist));
                // Check condition
                if ($has['const'] && ($has['null'] || $has['unfetched'] || $has['duplicated'])) {
                    $this->addSpot('WARNING', false, 'Array key may be overwritten when defining as a property and using constants', $arr->getLine());
                }
            }
        }
    }
IncompPropertyArray