<commit_before><?php

declare(strict_types=1);

namespace Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_;

use Rector\BetterPhpDocParser\ValueObject\AroundSpaces;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\PhpAttribute\Contract\ManyPhpAttributableTagNodeInterface;
use Rector\PhpAttribute\Contract\PhpAttributableTagNodeInterface;

final class JoinTableTagValueNode extends AbstractDoctrineTagValueNode implements PhpAttributableTagNodeInterface, ManyPhpAttributableTagNodeInterface
{
    /**
     * @var string
     */
    private const JOIN_COLUMNS = 'joinColumns';

    /**
     * @var string
     */
    private const INVERSE_JOIN_COLUMNS = 'inverseJoinColumns';

    /**
     * @var string
     */
    private $name;

    /**
     * @var JoinColumnTagValueNode[]
     */
    private $joinColumns = [];

    /**
     * @var JoinColumnTagValueNode[]
     */
    private $inverseJoinColumns = [];

    /**
     * @var AroundSpaces|null
     */
    private $inverseJoinColumnsAroundSpaces;

    /**
     * @var AroundSpaces|null
     */
    private $joinColumnsAroundSpaces;

    /**
     * @var string|null
     */
    private $schema;

    /**
     * @param JoinColumnTagValueNode[] $joinColumns
     * @param JoinColumnTagValueNode[] $inverseJoinColumns
     */
    public function __construct(
        string $name,
        ?string $schema = null,
        array $joinColumns = [],
        array $inverseJoinColumns = [],
        ?string $originalContent = null,
        ?AroundSpaces $joinColumnsAroundSpaces = null,
        ?AroundSpaces $inverseJoinColumnsAroundSpaces = null
    ) {
        $this->name = $name;
        $this->schema = $schema;
        $this->joinColumns = $joinColumns;
        $this->inverseJoinColumns = $inverseJoinColumns;
        $this->resolveOriginalContentSpacingAndOrder($originalContent);
        $this->inverseJoinColumnsAroundSpaces = $inverseJoinColumnsAroundSpaces;
        $this->joinColumnsAroundSpaces = $joinColumnsAroundSpaces;
    }

    public function __toString(): string
    {
        $items = $this->createItems();
        $items = $this->makeKeysExplicit($items);

        return $this->printContentItems($items);
    }

    public function getShortName(): string
    {
        return '@ORM\JoinTable';
    }

    /**
     * @return mixed[]
     */
    public function getAttributableItems(): array
    {
        $items = [];

        $items['name'] = $this->name;

        if ($this->schema !== null) {
            $items['schema'] = $this->schema;
        }

        return $items;
    }

    /**
     * @return array<string, mixed[]>
     */
    public function provide(): array
    {
        $items = [];

        foreach ($this->joinColumns as $joinColumn) {
            $items[$joinColumn->getShortName()] = $joinColumn->getAttributableItems();
        }

        foreach ($this->inverseJoinColumns as $inverseJoinColumn) {
            $items['@ORM\InverseJoinColumn'] = $inverseJoinColumn->getAttributableItems();
        }

        return $items;
    }

    public function getAttributeClassName(): string
    {
        return 'TBA';
    }

    /**
     * @return string[]
     */
    private function createItems(): array
    {
        $items = [];

        $items['name'] = sprintf('"%s"', $this->name);

        if ($this->schema !== null) {
            $items['schema'] = sprintf('"%s"', $this->schema);
        }

        $joinColumnItems = $this->createJoinColumnItems(self::JOIN_COLUMNS, self::INVERSE_JOIN_COLUMNS);
        return array_merge($items, $joinColumnItems);
    }
<commit_msg>Fix parsing JoinTable without table name explicitly set (#5236)<commit_after><?php

declare(strict_types=1);

namespace Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_;

use Rector\BetterPhpDocParser\ValueObject\AroundSpaces;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\PhpAttribute\Contract\ManyPhpAttributableTagNodeInterface;
use Rector\PhpAttribute\Contract\PhpAttributableTagNodeInterface;

final class JoinTableTagValueNode extends AbstractDoctrineTagValueNode implements PhpAttributableTagNodeInterface, ManyPhpAttributableTagNodeInterface
{
    /**
     * @var string
     */
    private const JOIN_COLUMNS = 'joinColumns';

    /**
     * @var string
     */
    private const INVERSE_JOIN_COLUMNS = 'inverseJoinColumns';

    /**
     * @var string|null
     */
    private $name;

    /**
     * @var JoinColumnTagValueNode[]
     */
    private $joinColumns = [];

    /**
     * @var JoinColumnTagValueNode[]
     */
    private $inverseJoinColumns = [];

    /**
     * @var AroundSpaces|null
     */
    private $inverseJoinColumnsAroundSpaces;

    /**
     * @var AroundSpaces|null
     */
    private $joinColumnsAroundSpaces;

    /**
     * @var string|null
     */
    private $schema;

    /**
     * @param JoinColumnTagValueNode[] $joinColumns
     * @param JoinColumnTagValueNode[] $inverseJoinColumns
     */
    public function __construct(
        ?string $name,
        ?string $schema = null,
        array $joinColumns = [],
        array $inverseJoinColumns = [],
        ?string $originalContent = null,
        ?AroundSpaces $joinColumnsAroundSpaces = null,
        ?AroundSpaces $inverseJoinColumnsAroundSpaces = null
    ) {
        $this->name = $name;
        $this->schema = $schema;
        $this->joinColumns = $joinColumns;
        $this->inverseJoinColumns = $inverseJoinColumns;
        $this->resolveOriginalContentSpacingAndOrder($originalContent);
        $this->inverseJoinColumnsAroundSpaces = $inverseJoinColumnsAroundSpaces;
        $this->joinColumnsAroundSpaces = $joinColumnsAroundSpaces;
    }

    public function __toString(): string
    {
        $items = $this->createItems();
        $items = $this->makeKeysExplicit($items);

        return $this->printContentItems($items);
    }

    public function getShortName(): string
    {
        return '@ORM\JoinTable';
    }

    /**
     * @return mixed[]
     */
    public function getAttributableItems(): array
    {
        $items = [];
        
        if ($this->name !== null) {
            $items['name'] = $this->name;
        }

        if ($this->schema !== null) {
            $items['schema'] = $this->schema;
        }

        return $items;
    }

    /**
     * @return array<string, mixed[]>
     */
    public function provide(): array
    {
        $items = [];

        foreach ($this->joinColumns as $joinColumn) {
            $items[$joinColumn->getShortName()] = $joinColumn->getAttributableItems();
        }

        foreach ($this->inverseJoinColumns as $inverseJoinColumn) {
            $items['@ORM\InverseJoinColumn'] = $inverseJoinColumn->getAttributableItems();
        }

        return $items;
    }

    public function getAttributeClassName(): string
    {
        return 'TBA';
    }

    /**
     * @return string[]
     */
    private function createItems(): array
    {
        $items = [];

        if ($this->name !== null) {
            $items['name'] = sprintf('"%s"', $this->name);
        }

        if ($this->schema !== null) {
            $items['schema'] = sprintf('"%s"', $this->schema);
        }

        $joinColumnItems = $this->createJoinColumnItems(self::JOIN_COLUMNS, self::INVERSE_JOIN_COLUMNS);
        return array_merge($items, $joinColumnItems);
    }

{'fraction_non_alphanumeric': 0.12741978255104747, 'fraction_numerical': 0.0007955449482895784, 'mean_word_length': 2.6386878919440426, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4050287', 'n_tokens_mistral': 2255, 'n_tokens_neox': 2158, 'n_words': 374}