<commit_before><?php
namespace Psalm\Type\Atomic;

use function array_keys;
use function array_map;
use function count;
use function get_class;
use function implode;
use function is_int;
use function sort;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TypeCombination;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\UnionTemplateHandler;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Union;

/**
 * Represents an array where we know its key values
 */
class TKeyedArray extends \Psalm\Type\Atomic
{
    /**
     * @var non-empty-array<string|int, Union>
     */
    public $properties;

    /**
     * @var array<string, bool>|null
     */
    public $class_strings = null;

    /**
     * @var bool - whether or not the objectlike has been created from an explicit array
     */
    public $sealed = false;

    /**
     * Whether or not the previous array had an unknown key type
     *
     * @var ?Union
     */
    public $previous_key_type = null;

    /**
     * Whether or not to allow new properties to be asserted on the given array
     *
     * @var ?Union
     */
    public $previous_value_type = null;

    /**
     * @var bool - if this is a list of sequential elements
     */
    public $is_list = false;

    public const KEY = 'array';

    /**
     * Constructs a new instance of a generic type
     *
     * @param non-empty-array<string|int, Union> $properties
     * @param array<string, bool> $class_strings
     */
    public function __construct(array $properties, ?array $class_strings = null)
    {
        $this->properties = $properties;
        $this->class_strings = $class_strings;
    }

    public function __toString(): string
    {
        $property_strings = array_map(
            function ($name, Union $type): string {
                if ($this->is_list && $this->sealed) {
                    return (string) $type;
                }

                if (\is_string($name) && \preg_match('/[ "\'\\\\.\n:]/', $name)) {
                    $name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
                }

                return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type;
            },
            array_keys($this->properties),
            $this->properties
        );

        if (!$this->is_list) {
            sort($property_strings);
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' . implode(', ', $property_strings) . '}';
    }

    public function getId(bool $nested = false): string
    {
        $property_strings = array_map(
            function ($name, Union $type): string {
                if ($this->is_list && $this->sealed) {
                    return $type->getId();
                }

                if (\is_string($name) && \preg_match('/[ "\'\\\\.\n:]/', $name)) {
                    $name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
                }

                return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type->getId();
            },
            array_keys($this->properties),
            $this->properties
        );

        if (!$this->is_list) {
            sort($property_strings);
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' .
                implode(', ', $property_strings) .
                '}'
                . ($this->previous_value_type
                    ? '<' . ($this->previous_key_type ? $this->previous_key_type->getId() . ', ' : '')
                        . $this->previous_value_type->getId() . '>'
                    : '');
    }

    /**
     * @param  array<string, string> $aliased_classes
     *
     */
    public function toNamespacedString(
        ?string $namespace,
        array $aliased_classes,
        ?string $this_class,
        bool $use_phpdoc_format
    ): string {
        if ($use_phpdoc_format) {
            return $this->getGenericArrayType()->toNamespacedString(
                $namespace,
                $aliased_classes,
                $this_class,
                $use_phpdoc_format
            );
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' .
                implode(
                    ', ',
                    array_map(<commit_msg>Only show interesting array intersections<commit_after><?php
namespace Psalm\Type\Atomic;

use function array_keys;
use function array_map;
use function count;
use function get_class;
use function implode;
use function is_int;
use function sort;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TypeCombination;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\UnionTemplateHandler;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Union;

/**
 * Represents an array where we know its key values
 */
class TKeyedArray extends \Psalm\Type\Atomic
{
    /**
     * @var non-empty-array<string|int, Union>
     */
    public $properties;

    /**
     * @var array<string, bool>|null
     */
    public $class_strings = null;

    /**
     * @var bool - whether or not the objectlike has been created from an explicit array
     */
    public $sealed = false;

    /**
     * Whether or not the previous array had an unknown key type
     *
     * @var ?Union
     */
    public $previous_key_type = null;

    /**
     * Whether or not to allow new properties to be asserted on the given array
     *
     * @var ?Union
     */
    public $previous_value_type = null;

    /**
     * @var bool - if this is a list of sequential elements
     */
    public $is_list = false;

    public const KEY = 'array';

    /**
     * Constructs a new instance of a generic type
     *
     * @param non-empty-array<string|int, Union> $properties
     * @param array<string, bool> $class_strings
     */
    public function __construct(array $properties, ?array $class_strings = null)
    {
        $this->properties = $properties;
        $this->class_strings = $class_strings;
    }

    public function __toString(): string
    {
        $property_strings = array_map(
            function ($name, Union $type): string {
                if ($this->is_list && $this->sealed) {
                    return (string) $type;
                }

                if (\is_string($name) && \preg_match('/[ "\'\\\\.\n:]/', $name)) {
                    $name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
                }

                return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type;
            },
            array_keys($this->properties),
            $this->properties
        );

        if (!$this->is_list) {
            sort($property_strings);
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' . implode(', ', $property_strings) . '}';
    }

    public function getId(bool $nested = false): string
    {
        $property_strings = array_map(
            function ($name, Union $type): string {
                if ($this->is_list && $this->sealed) {
                    return $type->getId();
                }

                if (\is_string($name) && \preg_match('/[ "\'\\\\.\n:]/', $name)) {
                    $name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
                }

                return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type->getId();
            },
            array_keys($this->properties),
            $this->properties
        );

        if (!$this->is_list) {
            sort($property_strings);
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' .
                implode(', ', $property_strings) .
                '}'
                . ($this->previous_value_type
                    && (!$this->previous_value_type->isMixed()
                        || ($this->previous_key_type && !$this->previous_key_type->isArrayKey()))
                    ? '<' . ($this->previous_key_type ? $this->previous_key_type->getId() . ', ' : '')
                        . $this->previous_value_type->getId() . '>'
                    : '');
    }

    /**
     * @param  array<string, string> $aliased_classes
     *
     */
    public function toNamespacedString(
        ?string $namespace,
        array $aliased_classes,
        ?string $this_class,
        bool $use_phpdoc_format
    ): string {
        if ($use_phpdoc_format) {
            return $this->getGenericArrayType()->toNamespacedString(
                $namespace,
                $aliased_classes,
                $this_class,
                $use_phpdoc_format
            );
        }

        /** @psalm-suppress MixedOperand */
        return static::KEY . '{' .
                implode(
                    ', ',
                    array_map(
{'fraction_non_alphanumeric': 0.14288931426641144, 'fraction_numerical': 0.0, 'mean_word_length': 1.7212009803921569, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 68, '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': '6121015', 'n_tokens_mistral': 2639, 'n_tokens_neox': 2520, 'n_words': 560}